A comprehensive TypeScript application for analyzing Bitcoin inscription holders across collections using the BestInSlot API. This tool fetches collection data, analyzes holder patterns, and generates filtered reports for investment and analysis purposes.
๐ฐ Read the full article on Medium - Detailed explanation of the project, architecture, and implementation.
Watch the application in action - see how it fetches data, processes large datasets, and generates comprehensive holder analysis reports.
- Collection Data Fetching: Automatically retrieves all inscription collections from BestInSlot API
- Bitmap Holder Analysis: Fetches comprehensive bitmap holder data
- Cross-Collection Analysis: Identifies wallets holding inscriptions across multiple collections
- Smart Filtering: Filters holders based on inscription count thresholds
- Automated File Management: Generates timestamped reports with automatic latest file detection
- Large Data Handling: Automatic chunking and merging for extremely large datasets
- Rate Limiting: Built-in delays to respect API rate limits
- Comprehensive Logging: Detailed logging with timestamps and context
- Error Handling: Robust error handling with graceful fallbacks
- Modular Architecture: Clean, maintainable, and testable codebase
1. Collection Fetching โ 2. Bitmap Fetching โ 3. Holder Analysis โ 4. Data Aggregation โ 5. Filtering โ 6. Report Generation
โโโ API: BestInSlot Collections
โโโ API: BestInSlot Bitmaps
โโโ API: Collection Holders
โโโ Merge holder data
โโโ Filter by criteria
โโโ Generate timestamped reports
src/
โโโ index.ts # Main application entry point (65 lines)
โโโ services/ # Business logic services
โ โโโ index.ts # Service exports
โ โโโ api.ts # BestInSlot API interactions
โ โโโ fileManager.ts # File system operations
โ โโโ dataProcessor.ts # Data analysis and processing
โ โโโ orchestrator.ts # Application workflow coordination
โโโ types/
โ โโโ index.ts # TypeScript interfaces (ICollection, IHolder, IBitmap)
โโโ utils/
โ โโโ logger.ts # Advanced logging utility
โ โโโ delay.ts # Rate limiting utility
โโโ __tests__/
โโโ calculator.test.ts # Unit tests
data/ # Generated data files (gitignored)
โโโ collections-YYYY-MM-DDTHH-mm-ss-sssZ.json
โโโ bitmapList-YYYY-MM-DDTHH-mm-ss-sssZ.json
โโโ holderSummary-YYYY-MM-DDTHH-mm-ss-sssZ.json
โโโ holderSummary-YYYY-MM-DDTHH-mm-ss-sssZ-chunk1.json (for large datasets)
โโโ FinalResult-YYYY-MM-DDTHH-mm-ss-sssZ.json
- Node.js (version 18 or higher)
- npm or yarn
- BestInSlot API Key (Get one here)
-
Clone the repository
git clone https://github.com/michalstefanow/bitcoin-ordinal-holder-indexer cd bitcoin-ordinal-holder-indexer
-
Install dependencies
npm install
-
Environment Setup Create a
.env
file in the project root:BEST_IN_SLOT=your_api_key_here
-
Build the project
npm run build
Run the complete analysis pipeline:
npm run dev
This executes:
- Collection Fetching: Downloads all inscription collections
- Bitmap Fetching: Downloads all bitmap holder data
- Holder Summarization: Analyzes holders across collections and bitmaps
- Data Filtering: Applies filtering criteria (holders with โฅ10 inscriptions)
The new modular architecture provides multiple execution modes:
import { runFullPipeline } from './services';
// Execute complete analysis pipeline
await runFullPipeline();
import { runDataFetchingOnly } from './services';
// Update source data without re-analyzing
await runDataFetchingOnly();
import { runAnalysisOnly } from './services';
// Re-analyze existing data
await runAnalysisOnly();
import { runHolderSummarizationOnly, runHolderFilteringOnly } from './services';
// Summarize holders only
await runHolderSummarizationOnly();
// Filter holders only
await runHolderFilteringOnly();
import { getAnalysisStatus } from './services';
// Get current analysis status
const status = await getAnalysisStatus();
console.log(`Qualified holders: ${status.qualifiedHolders}`);
You can also use individual services directly:
import {
fetchCollectionList,
saveCollectionsToFile,
getLatestCollectionsFile
} from './services';
// Fetch and save collections
const collections = await fetchCollectionList();
await saveCollectionsToFile(collections);
// Get latest collections file
const latestFile = await getLatestCollectionsFile();
The application generates several types of timestamped files:
- Raw collection data from BestInSlot API
- Contains collection metadata, statistics, and identifiers
- Bitmap holder data from BestInSlot API
- Contains wallet addresses and their bitmap inscriptions
- Aggregated holder data across all collections and bitmaps
- Maps wallet addresses to all their inscription IDs
- May be split into chunks for large datasets (
holderSummary-*-chunk*.json
)
- Filtered holder data meeting criteria (โฅ10 inscriptions)
- Primary output for investment analysis
Variable | Description | Required |
---|---|---|
BEST_IN_SLOT |
BestInSlot API key | Yes |
The default filtering threshold is 10 inscriptions per wallet. This can be modified in src/services/dataProcessor.ts
:
// In filterHolders() function
if (inscriptions && inscriptions.length >= 10) { // Change this number
filteredHoldersSummary[wallet] = inscriptions;
}
Script | Description |
---|---|
npm run build |
Compile TypeScript to JavaScript |
npm run dev |
Run the application in development mode |
npm run start |
Run the compiled application |
npm run test |
Run unit tests |
npm run lint |
Run ESLint for code quality |
npm run format |
Format code with Prettier |
- Handles all BestInSlot API interactions
- Implements rate limiting and error handling
- Supports pagination for large datasets
- Manages all file system operations
- Handles automatic chunking for large files
- Implements safe JSON serialization
- Merges chunked files automatically
- Processes and analyzes holder data
- Implements cross-collection aggregation
- Handles data validation and cleaning
- Applies filtering criteria
- Coordinates the complete application workflow
- Provides flexible execution modes
- Manages error handling and logging
- Modular Design: Each service has a single responsibility
- Error Isolation: Errors in one service don't affect others
- Memory Efficiency: Handles extremely large datasets through chunking
- Type Safety: Full TypeScript support with strict typing
- Professional Logging: Structured logging with context and timestamps
The modular architecture enables easy testing:
// Test individual services
import { fetchCollectionList } from './services/api';
import { getLatestCollectionsFile } from './services/fileManager';
import { filterHolders } from './services/dataProcessor';
// Each service can be tested in isolation
- Automatic Chunking: Files >50MB are automatically split
- Memory Management: Efficient handling of large datasets
- Safe Serialization: Robust JSON serialization with fallbacks
- Rate Limiting: 1.5-second delays between requests
- Pagination: Efficient data fetching in batches
- Error Recovery: Graceful handling of API failures
The modular architecture enables easy future enhancements:
- Database Integration: Add database service for persistent storage
- Web API: Create REST API service for external access
- Real-time Processing: Add streaming service for live data
- Advanced Analytics: Add analytics service for deeper insights
- Configuration Management: Add config service for dynamic settings
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Email: michalstefanow.marek@gmail.com
- Telegram: @mylord1_1
- GitHub: @michalstefanow
API Key Error
Error: BEST_IN_SLOT API key is required
Solution: Ensure your .env
file contains the correct API key.
Memory Issues
Error: Invalid string length
Solution: The application automatically handles large datasets through chunking.
File Not Found
Error: No collections files found in data directory
Solution: Run the data fetching operations first to generate the required files.
If you encounter issues:
- Check the logs for detailed error messages
- Ensure your API key is valid and has sufficient permissions
- Verify your Node.js version is 18 or higher
- Check the troubleshooting section above
- Identify high-value holders across multiple collections
- Analyze holder patterns and trends
- Generate investment-ready data reports
- Track holder distribution across collections
- Monitor cross-collection holder behavior
- Analyze market concentration and diversity
- Large-scale holder data analysis
- Pattern recognition and trend analysis
- Statistical modeling and predictions
The application is designed for professional use in Bitcoin inscription analysis and provides a solid foundation for advanced research and investment strategies.