A modern blockchain explorer for the Noot smart contract platform, built with React Router.
- Chain Statistics: View total transactions, token count, and recent activity
- Transaction Browser: Browse all transactions with operation types and details
- Token Registry: View all created tokens with supply and holder information
- Token Details: Inspect individual tokens and their balance distributions
- Message Sender: Create and send contract messages directly from the UI
- Preflight Validation: Validate messages before sending to catch errors early
- Network Filtering: Automatically filters transactions by configured network (testnet/mainnet)
- Real-time Updates: Live updates via Krist websocket connection
- Node.js 18+
- pnpm
- A running Noot client (configured via
config.json)
From the repository root:
pnpm installCreate a config.json file in the explorer directory:
{
"dbPath": "chain.db",
"network": "T",
"privateKey": "your_krist_private_key_here",
"unsafe": false
}Configuration Options:
dbPath: Path to the SQLite database file (default:chain.db)network: Network to operate on -"T"for testnet,"N"for mainnetprivateKey: Your Krist private key (required for sending messages)unsafe: Set totrueto disable error isolation (not recommended)kristApiUrl: Optional custom Krist API URLstartFromTransaction: Optional transaction ID to start syncing from
Start the development server:
pnpm devThe explorer will be available at http://localhost:5173
Build the application:
pnpm buildStart the production server:
pnpm start- React Router 7: Full-stack React framework with server-side rendering
- Vite: Fast build tool and dev server
- TypeScript: Type-safe development
- Drizzle ORM: Type-safe database queries
- @tmpim/noot: Core Noot client library
packages/explorer/
├── app/
│ ├── components/ # Reusable UI components
│ │ ├── Header.tsx # Navigation header
│ │ ├── Footer.tsx # Page footer
│ │ └── Layout.tsx # Page layout wrapper
│ ├── lib/
│ │ ├── api.server.ts # Server-side API functions
│ │ ├── format.ts # Formatting utilities
│ │ └── noot-context.ts # Noot client singleton
│ ├── routes/ # Page routes
│ │ ├── home.tsx # Dashboard
│ │ ├── transactions.tsx # Transaction list
│ │ ├── tokens.tsx # Token list
│ │ ├── token-detail.tsx # Token details
│ │ └── send.tsx # Message sender
│ ├── root.tsx # Root layout
│ ├── routes.ts # Route configuration
│ └── styles.css # Global styles
├── config.json # Noot client configuration
└── react-router.config.ts # React Router configuration
Displays chain statistics and recent activity:
- Total transactions and daily count
- Token count
- Recent transactions (last 10)
- Recent tokens (last 5)
Browse all transactions with:
- Transaction hash
- Operation type (Genesis, Create Token, Mint, Transfer, etc.)
- From/To addresses
- Amount
- Timestamp
View all tokens with:
- Token ID
- Name and symbol
- Owner address
- Total supply
- Holder count
Detailed view of a specific token:
- Token metadata
- Total supply and holder count
- Complete balance distribution table
Create and send contract messages:
- Operation selector: Choose from Genesis, Create Token, Mint, Transfer, etc.
- Dynamic form fields: Form adapts based on selected operation
- Preflight validation: Test messages before sending
- Simulated state preview: See what the chain state will look like after the message
- Network enforcement: Automatically uses the configured network
The explorer supports all Noot contract operations:
- Genesis (G): Initialize the chain
- Create Token (CT): Create a new token
- Mint Token (MT): Mint tokens to an address
- Transfer Token (TT): Transfer tokens between addresses
- Burn Token (BT): Burn tokens from circulation
- Transfer Token Ownership (TTO): Transfer token ownership
- Flag (F): Set a flag message
getStats(): Get chain statisticsgetTransactions(limit, offset): Get paginated transactionsgetTokens(limit, offset): Get paginated tokensgetToken(id): Get token detailspreflightMessage(formData): Validate a message without sendingsendMessage(formData): Send a message to the blockchain
The explorer automatically filters transactions based on the configured network:
- Testnet (
"T"): Only processes testnet messages - Mainnet (
"N"): Only processes mainnet messages
Messages from other networks are silently ignored, ensuring clean separation between environments.
Before sending a message, you can use the preflight feature to:
- Validate the message structure
- Check if the operation will succeed
- Preview the simulated chain state after the message
- See token counts and balances
This helps catch errors before spending KST on failed transactions.
The explorer uses a modern, clean design with:
- Dark theme optimized for readability
- Responsive layout for mobile and desktop
- Color-coded operation badges
- Hover effects and transitions
- Accessible form controls
The dev server supports HMR for fast iteration:
pnpm devChanges to routes, components, and styles will update instantly.
All routes are fully typed with React Router's type generation:
pnpm typegenThis generates types for loaders, actions, and route parameters.
Inspect the SQLite database:
sqlite3 chain.dbUseful queries:
-- View recent transactions
SELECT * FROM krist_transactions ORDER BY id DESC LIMIT 10;
-- View all tokens
SELECT * FROM noots WHERE message_op = 'CT';
-- View chain state
SELECT * FROM chain_state ORDER BY id DESC LIMIT 1;If port 5173 is in use:
pnpm dev --port 3000If you get a "database is locked" error, ensure no other processes are using the database:
# Stop all dev servers
# Delete the database and restart
rm chain.db
pnpm devIf you're seeing unexpected transactions, verify your config.json network setting matches your intent:
"T"for testnet"N"for mainnet
Contributions are welcome! Please ensure:
- TypeScript types are correct
- Code follows existing style
- New features include appropriate error handling
- UI changes maintain accessibility
MIT License - see the root LICENSE file for details.