BLOBKIT v1.0.1 [ETHEREUM/EIP-4844]
[STATUS]
● ONLINE
● NPM PUBLISHED
● MAINNET READY
[LINKS]
GITHUB
NPM
[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
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
REPO: github.com/ETHCF/blobkit
LICENSE: Apache 2.0 - Fork freely
ISSUES: Bug reports and feature requests welcome