BLOBKIT v1.0.1 [ETHEREUM/EIP-4844]
[STATUS]
● ONLINE
● NPM PUBLISHED
● MAINNET READY
[METRICS]
128KB BLOB CAPACITY
~10-100X COST REDUCTION
CRYPTOGRAPHIC PROOFS
TypeScript SDK for Ethereum blob transactions (EIP-4844)
Ephemeral data storage with cryptographic guarantees
[01] QUICKSTART
▶ GET STARTED
[STEP 1] INSTALL & SETUP
$npm install blobkit dotenv
[STEP 2] BASIC USAGE
[TYPESCRIPT]
import { createFromEnv, initializeForDevelopment } from 'blobkit' import dotenv from 'dotenv' // Load environment variables dotenv.config() // 1. Initialize KZG setup (required) await initializeForDevelopment() // 2. Create client from environment variables (recommended) const blobkit = createFromEnv() // 3. Write data to blob space const receipt = await blobkit.writeBlob({ message: 'Hello, blob space!', timestamp: Date.now() }) console.log('✓ Blob stored:', receipt.blobHash) // 4. Read data back with automatic decoding const blobData = await blobkit.readBlobWithMeta(receipt.blobHash) console.log('✓ Data retrieved:', blobData.data)
✓ SUCCESS: You've stored your first blob!
- → Data expires automatically in ~2 weeks
- → Costs 10-100x less than calldata
- → Same security as Ethereum mainnet
NEXT: See advanced use cases and configuration options below ↓
[02] INSTALLATION
↓ PACKAGE
[NPM]
$npm install blobkit
[YARN]
$yarn add blobkit
[PNPM]
$pnpm add blobkit
[ENVIRONMENT SETUP]
$# Create .env file in your project root
cat > .env << 'EOF'
# Required
RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY
PRIVATE_KEY=0x1234567890abcdef...
# Optional
CHAIN_ID=1
ARCHIVE_URL=https://your-blob-archive.com
DEFAULT_CODEC=application/json
COMPRESSION_LEVEL=3
EOF
# SECURITY: Add .env to .gitignore
echo ".env" >> .gitignore
⚠ SECURITY WARNING:
Never commit your .env file or private keys to version control. Always add .env to your .gitignore file.
REQUIREMENTS: Node.js ≥16.0.0 | TypeScript recommended
[03] BASIC USAGE
● COMPLETE
Complete example showing write → read → verify workflow
[TYPESCRIPT]
import { createFromEnv, initializeForDevelopment } from 'blobkit' import dotenv from 'dotenv' // Load environment variables dotenv.config() // Initialize KZG setup (required) await initializeForDevelopment() // Create client from environment (recommended) const blobkit = createFromEnv() // Write blob with metadata const receipt = await blobkit.writeBlob({ message: 'Hello blob space', timestamp: Date.now(), gameState: { level: 1, score: 100 } }, { appId: 'my-game', codec: 'application/json', ttlBlocks: 100800 // ~2 weeks }) console.log('Transaction hash:', receipt.txHash) console.log('Blob hash:', receipt.blobHash) console.log('Content hash:', receipt.contentHash) // Read raw blob data (works with tx hash or blob hash) const rawData = await blobkit.readBlob(receipt.txHash) console.log('Retrieved raw data (Uint8Array):', rawData) // Read with metadata and automatic decoding const blobData = await blobkit.readBlobWithMeta(receipt.blobHash) console.log('Decoded data:', blobData.data) console.log('Metadata:', blobData.meta) // Verify blob integrity const isValid = await blobkit.verifyBlob(rawData, receipt.blobHash) console.log('Blob valid:', isValid)
OUTPUT: Transaction submitted → Data stored → Integrity verified
[04] USE CASES
◆ APPLICATIONS
💬EPHEMERAL CHAT
Decentralized messaging with auto-expiry. Perfect for sensitive communications.
[TYPESCRIPT]
// Ephemeral messaging system const receipt = await blobkit.writeBlob({ from: '0x742d35Cc...', to: '0x8ba1f109...', message: 'Meet at the old bridge at midnight', encrypted: true }, { appId: 'secureChat', ttlBlocks: 50400 // 1 week }) // Message automatically expires - no cleanup needed
📊PRICE ORACLES
High-frequency data feeds with cryptographic integrity guarantees.
[TYPESCRIPT]
// High-frequency price feed const priceData = { symbol: 'ETH/USD', price: 2456.78, timestamp: Date.now(), sources: ['coinbase', 'binance', 'uniswap'], confidence: 0.99 } await blobkit.writeBlob(priceData, { appId: 'priceOracle', ttlBlocks: 7200 // 1 day })
🎮TURN-BASED GAMES
Store game moves with verifiable proofs. Trustless gaming without chain bloat.
[TYPESCRIPT]
// Chess move with proof const move = { gameId: 'tournament_finals_001', move: 'Qh5#', fen: 'r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R', signature: '0x...' } const receipt = await blobkit.writeBlob(move, { appId: 'chessEngine', codec: 'application/json' })
🔐PROOF OF EXISTENCE
Timestamp documents without revealing content. IP protection and legal proofs.
[TYPESCRIPT]
// Document timestamping const proof = { documentHash: '0xabc123...', title: 'Research Paper Draft v3', author: '0x742d35Cc...', timestamp: Date.now() } // Proves existence without revealing content await blobkit.writeBlob(proof, { appId: 'timestamper' })
WHY BLOB SPACE?
COST EFFICIENT
10-100x cheaper than calldata
AUTO EXPIRY
No cleanup required
CRYPTOGRAPHIC
Same security as L1
[05] KZG SETUP
▲ CRYPTOGRAPHY
PRODUCTION SETUP
Uses official Ethereum KZG ceremony parameters. Required for mainnet.
[TYPESCRIPT]
import { initializeForProduction } from 'blobkit' // Production: Uses official KZG trusted setup // Download files from: https://github.com/ethereum/kzg-ceremony-sequencer await initializeForProduction( '/path/to/g1.point', '/path/to/g2.point', 'text' // or 'binary' )
DEVELOPMENT SETUP
Mock setup for testing. Fast initialization but NOT secure.
[TYPESCRIPT]
import { initializeForDevelopment } from 'blobkit' // Development: Uses mock setup - DO NOT use in production await initializeForDevelopment()
⚠ SECURITY WARNING
• Development setup uses known values - DO NOT use in production
• Production requires downloading ceremony files (~100MB)
• Files available at: github.com/ethereum/kzg-ceremony-sequencer
[06] ADVANCED FEATURES
★ EXPERT
🔧 CUSTOM CODECS
Extend BlobKit with custom data encoding. Register codecs for compressed formats, encrypted data, or application-specific serialization.
[TYPESCRIPT]
// Custom Codec Registration import { registerCodec } from 'blobkit' // Create custom codec for compressed game states const gameStateCodec = { encode(gameState: GameState): Uint8Array { const json = JSON.stringify(gameState) return compress(new TextEncoder().encode(json)) }, decode(data: Uint8Array): GameState { const decompressed = decompress(data) return JSON.parse(new TextDecoder().decode(decompressed)) } } // Register the codec registerCodec('application/x-gamestate+gzip', gameStateCodec) // Use custom codec const receipt = await blobkit.writeBlob(gameState, { codec: 'application/x-gamestate+gzip' })
📝 RICH METADATA
Every blob includes cryptographically-bound metadata with app identification, encoding information, timestamps, and content hashes.
[TYPESCRIPT]
// Rich Metadata Support const receipt = await blobkit.writeBlob(chatMessage, { appId: 'secure-chat', codec: 'application/json', ttlBlocks: 50400, // ~1 week expiry timestamp: Date.now(), contentHash: 'auto' // Automatically computed }) // Metadata is cryptographically bound to blob content const blobData = await blobkit.readBlobWithMeta(receipt.blobHash) console.log('App ID:', blobData.meta.appId) console.log('Expires at block:', blobData.meta.ttlBlocks) console.log('Content hash:', blobData.meta.contentHash)
🗄️ ARCHIVE INTEGRATION
Seamlessly access blobs beyond the ~2 week retention period via third-party archive services. Transparent fallback for expired data.
[TYPESCRIPT]
// Archive Support for Long-term Storage const blobkit = new BlobKit({ rpcUrl: 'https://mainnet.infura.io/v3/YOUR_KEY', chainId: 1, archiveUrl: 'https://blob-archive.service.com' // Third-party archive }, privateKey) // BlobKit automatically falls back to archive if blob expired from nodes try { const data = await blobkit.readBlob(oldBlobHash) // May be months old console.log('Retrieved from archive:', data) } catch (error) { console.log('Blob not found in nodes or archive') }
🗜️ BUILT-IN COMPRESSION
Automatic brotli compression maximizes blob utilization. Large payloads are compressed internally before encoding, allowing more data per blob while maintaining KZG compatibility.
[TYPESCRIPT]
// Automatic Compression // BlobKit automatically compresses data when writing blobs const blobkit = new BlobKit(config, privateKey) // Large data is automatically compressed during write const largeData = { data: new Array(10000).fill('test data'), metadata: { type: 'bulk_upload' } } // Compression happens internally const receipt = await blobkit.writeBlob(largeData, { appId: 'data-processor', compressionLevel: 3 // Optional: control compression (0-11) }) // Data is automatically decompressed when reading const retrieved = await blobkit.readBlobWithMeta(receipt.blobHash) console.log('Data restored:', retrieved.data)
Technical Highlights
•KZG commitment cryptographic proofs
•128KB blob capacity (optimized encoding)
•EIP-4844 compliant blob transactions
•Automatic gas price estimation
•TypeScript-first with full type safety
•Extensible codec architecture
[07] API REFERENCE
◊ FUNCTIONS
INITIALIZATION
[TYPESCRIPT]
import { initializeForDevelopment, initializeForProduction } from 'blobkit' // Development (uses mock setup - DO NOT use in production) await initializeForDevelopment() // Production (requires official KZG ceremony files) await initializeForProduction( g1Path: string, // Path to G1 points file g2Path: string, // Path to G2 points file format?: 'binary' | 'text' // File format (default: 'text') ) // Download ceremony files from: // https://github.com/ethereum/kzg-ceremony-sequencer
CLIENT SETUP
[TYPESCRIPT]
import { BlobKit, createFromEnv, createReadOnlyFromEnv } from 'blobkit' // Recommended: From environment variables with validation const blobkit = createFromEnv() // Read/write client const readOnly = createReadOnlyFromEnv() // Read-only client // Manual configuration const blobkit = new BlobKit({ rpcUrl: string, // Ethereum RPC endpoint (validated) chainId?: number, // Default: 1 (mainnet) archiveUrl?: string, // Optional blob archive service defaultCodec?: string, // Default: 'application/json' compressionLevel?: number // Brotli level 0-11 (default: 3) }, privateKey?: string) // Optional for read-only operations
WRITE OPERATIONS
[TYPESCRIPT]
// Write blob with metadata const receipt = await blobkit.writeBlob( payload: unknown, // Data to store meta?: { appId?: string, // App identifier codec?: string, // Encoding format ttlBlocks?: number, // Expiry in blocks timestamp?: number, // Custom timestamp contentHash?: string // Auto-computed if not provided } ) // Returns: { txHash, blobHash, blockNumber, contentHash }
READ OPERATIONS
[TYPESCRIPT]
// Read raw blob data as Uint8Array const rawData = await blobkit.readBlob( blobHashOrTxHash: string // Blob hash (0x01...) or tx hash ) // Returns: Uint8Array (raw blob data) // Read blob with metadata and automatic decoding const blobData = await blobkit.readBlobWithMeta( blobHashOrTxHash: string ) // Returns: { // data: any, // Decoded using registered codec // meta: BlobMeta, // Blob metadata // blobHash?: string, // Blob versioned hash // kzgCommitment?: string // KZG commitment // }
VERIFICATION
[TYPESCRIPT]
// Verify blob integrity const isValid = await blobkit.verifyBlob( data: Uint8Array, blobHash: string, blockNumber?: number ) // Verify entire blob transaction const result = await blobkit.verifyBlobTransaction(txHash: string) // Returns: { valid, blobHashes, blockNumber }
CODEC SYSTEM
[TYPESCRIPT]
import { registerCodec, hasCodec, listCodecs } from 'blobkit' // Register custom codec with validation registerCodec('application/x-custom', { encode: (data: MyType) => Uint8Array, decode: (data: Uint8Array) => MyType }) // Check codec availability const available = hasCodec('application/json') const all = listCodecs() // List all registered codecs // Codecs are used automatically with validation const receipt = await blobkit.writeBlob(data, { codec: 'application/x-custom' // Your custom codec })
VALIDATION & TYPE GUARDS
[TYPESCRIPT]
import { isValidBlobHash, isValidTxHash, isValidHexString } from 'blobkit' // Runtime validation with type guards if (isValidBlobHash(hash)) { // Safe to use as blob hash (0x01...) } if (isValidTxHash(hash)) { // Safe to use as transaction hash } if (isValidHexString(value, 64)) { // Valid 64-character hex string }
ERROR HANDLING
[TYPESCRIPT]
import { BlobKitError } from 'blobkit' try { const receipt = await blobkit.writeBlob(data) } catch (error) { if (error instanceof BlobKitError) { console.log('Code:', error.code) console.log('Message:', error.message) console.log('Details:', error.details) } }
Configuration
INVALID_CONFIG: Missing RPC URL
INVALID_RPC_URL: Invalid URL format
INVALID_CHAIN_ID: Chain ID out of range
INVALID_PRIVATE_KEY: Invalid key format
INVALID_COMPRESSION_LEVEL: Level 0-11 only
Data & Validation
INVALID_PAYLOAD: Null/undefined data
INVALID_DATA: Empty data
DATA_TOO_LARGE: Exceeds blob capacity
INVALID_BLOB_HASH: Invalid hash format
INVALID_TX_HASH: Invalid tx hash
INVALID_HASH_FORMAT: Not blob/tx hash
Operations
NO_WALLET: Private key required
TX_FAILED: Transaction rejected
BLOB_NOT_FOUND: Blob expired/missing
VERIFICATION_FAILED: Integrity check failed
NO_TRUSTED_SETUP: KZG setup required
[08] PROJECT STRUCTURE
◊ MODULES
Enterprise-grade architecture with modular design:
src/kzg/KZG commitment implementation and trusted setup management
src/blob/Blob encoding/decoding utilities with EIP-4844 compliance
src/writer/Transaction construction and submission with fee estimation
src/verifier/Blob verification and integrity checks with inclusion proofs
src/codecs/Data encoding system (JSON, raw binary, extensible)
src/types/TypeScript type definitions and validation utilities
TESTING & QUALITY
91 Tests: Comprehensive test coverage
TypeScript: Full type safety
ESLint: Code quality enforcement
Prettier: Consistent formatting
Jest: Testing framework
Browser: Webpack bundling support
[09] BLOB FEES & COSTS
⚠ FINANCIAL
⚠ COST DISCLAIMER
• Variable Costs: Blob fees fluctuate based on network demand and can spike unexpectedly
• No Refunds: Failed transactions still consume gas and blob fees
• Market Risk: During high demand, blob fees can increase by 8x every 12 seconds
• Developer Responsibility: You are responsible for monitoring and controlling costs
• Production Warning: Always implement fee limits and monitoring in production applications
COST FORMULA & TECHNICAL SPECS
[TYPESCRIPT]
// EIP-4844 Blob Fee Calculation const totalCost = baseFee + (blobGasUsed * blobGasPrice) // Where: // baseFee: Standard Ethereum transaction fee (21,000 gas minimum) // blobGasUsed: 131,072 gas per blob (fixed) // blobGasPrice: Dynamic market price (starts at 1 wei, target 3 blobs/block) // Example calculation: const baseFee = 0.0001 ETH // ~20 gwei * 21,000 gas const blobGas = 131072 // Fixed per blob const blobGasPrice = 0.000001 ETH // ~1 gwei (varies by demand) const totalCost = baseFee + (blobGas * blobGasPrice) // = 0.0001 + 0.000131 = ~0.000231 ETH (~$0.50 at $2,000 ETH)
TECHNICAL SPECIFICATIONS
Max Blob Size: 128 KB (131,072 bytes)
Blobs per Block: 0-6 (target: 3)
Gas per Blob: 131,072 (fixed)
Min Blob Fee: 1 wei
Fee Multiplier: 1.125x per block above target
Data Lifetime: ~18 days (4096 epochs)
Block Time: ~12 seconds
COST COMPARISON
Calldata: ~16 gas per byte (~$2-20 per KB)
Blob Space: ~1 gas per byte (~$0.10-2 per KB)
Savings: 10-100x cheaper than calldata
Trade-off: Temporary vs permanent storage
* Costs vary significantly with network demand
FEE MANAGEMENT & CONTROLS
[TYPESCRIPT]
import { BlobKit } from 'blobkit' // Set maximum blob gas price for cost control const blobkit = new BlobKit({ rpcUrl: process.env.RPC_URL, chainId: 1 }, process.env.PRIVATE_KEY) // Write blob with fee limits const receipt = await blobkit.writeBlob(data, { maxFeePerBlobGas: BigInt('2000000000'), // 2 gwei maximum gasLimit: BigInt('100000') // Transaction gas limit }) // Monitor transaction status console.log('Transaction hash:', receipt.txHash) console.log('Actual blob gas used:', receipt.blobGasUsed) console.log('Actual blob gas price:', receipt.blobGasPrice)
REAL-TIME COST MONITORING
[TYPESCRIPT]
// Real-time fee monitoring before submission import { ethers } from 'ethers' const provider = new ethers.JsonRpcProvider(process.env.RPC_URL) // Get current blob base fee const block = await provider.getBlock('latest') const currentBlobBaseFee = block.blobGasUsed ? block.excessBlobGas / 126976 // EIP-4844 formula : 1 // Minimum 1 wei // Estimate total cost before submission const estimatedCost = baseFee + (131072 * currentBlobBaseFee) console.log('Estimated cost:', ethers.formatEther(estimatedCost), 'ETH') // Only proceed if cost is acceptable if (estimatedCost < maxAcceptableCost) { const receipt = await blobkit.writeBlob(data) }
LIVE FEE TRACKING RESOURCES
Fee Dashboards
ultrasound.money - Real-time blob fees
blobscan.com - Blob transaction explorer
dune.com/hildobby/blobs - Analytics
APIs & Tools
eth_blobBaseFee - RPC method
eth_gasPrice - Current gas price
eth_feeHistory - Historical data
PRODUCTION CHECKLIST
✓Implement maxFeePerBlobGas limits
✓Monitor blob base fee before transactions
✓Set up cost alerting and budgets
✓Handle transaction failures gracefully
✓Test fee estimation in staging
✓Document fee policies for users
IMPORTANT DISCLAIMERS
• BlobKit does not provide financial advice or cost guarantees
• Gas and blob fees are determined by Ethereum network consensus, not BlobKit
• Always test thoroughly on testnets before mainnet deployment
• Consider implementing circuit breakers for cost protection
• Monitor your applications continuously in production
• Blob data expires - ensure you have backup strategies if needed
[10] CONTRIBUTING
♦ DEVELOPMENT
Run tests
$npm test
Run tests with coverage
$npm run test:coverage
Lint code
$npm run lint
Format code with Prettier
$npm run format
Type check without emit
$npm run typecheck
Build SDK
$npm run build