Skip to main content
import * as Blob from 'voltaire-effect/primitives/Blob'
import * as Schema from 'effect/Schema'
import { Effect } from 'effect'
import { KZGLive } from 'voltaire-effect/crypto/KZG'

// Constants
Blob.SIZE                    // 131072 (128KB)
Blob.FIELD_ELEMENTS_PER_BLOB // 4096
Blob.BYTES_PER_FIELD_ELEMENT // 32
Blob.MAX_PER_TRANSACTION     // 6
Blob.MAX_DATA_PER_BLOB       // 126972 (usable data bytes)

// From raw 131072 bytes
const blob = await Effect.runPromise(Blob.from(blobBytes))

// From arbitrary data (pads to 128KB)
const padded = await Effect.runPromise(Blob.fromData(myData))

// Extract original data (pure, never throws)
const original = Blob.toData(blob)

// Validate size (pure)
if (Blob.isValid(data)) { /* exactly 128KB */ }

// Schema validation
Schema.decodeSync(Blob.Schema)(blobBytes)

// Gas calculations
const gas = await Effect.runPromise(Blob.calculateGas(3)) // 393216
const count = await Effect.runPromise(Blob.estimateBlobCount(200000)) // 2

// Split/join large data
const blobs = await Effect.runPromise(Blob.splitData(largeData))
const rejoined = await Effect.runPromise(Blob.joinData(blobs))

// KZG operations (require KZGService)
const program = Effect.gen(function* () {
  const commitment = yield* Blob.toCommitment(blob)
  const proof = yield* Blob.toProof(blob, commitment)
  const hash = yield* Blob.toVersionedHash(commitment)
  const isValid = yield* Blob.verify(blob, commitment, proof)
  return { commitment, proof, hash, isValid }
}).pipe(Effect.provide(KZGLive))

API Reference

Types

TypeDescription
BrandedBlob128KB blob (Uint8Array with brand)
Commitment48-byte KZG commitment
Proof48-byte KZG proof
VersionedHash32-byte versioned hash (0x01 prefix)

Constants

ConstantValueDescription
SIZE131072Blob size in bytes (128KB)
FIELD_ELEMENTS_PER_BLOB4096Field elements per blob
BYTES_PER_FIELD_ELEMENT32Bytes per field element
MAX_PER_TRANSACTION6Max blobs per transaction
MAX_DATA_PER_BLOB126972Max data bytes per blob
COMMITMENT_VERSION_KZG0x01KZG version byte
GAS_PER_BLOB131072Gas per blob

Constructors

FunctionTypeDescription
from(bytes: Uint8Array) => Effect<BrandedBlob, InvalidBlobDataSizeError>Create blob from bytes (auto-encodes if not 128KB)
fromData(data: Uint8Array) => Effect<BrandedBlob, InvalidBlobDataSizeError>Create blob from data with padding

Pure Functions

FunctionTypeDescription
isValid(blob: Uint8Array) => booleanCheck if exactly 128KB
isValidVersion(hash: VersionedHash) => booleanCheck version byte is 0x01
toData(blob: BrandedBlob) => Uint8ArrayExtract original data

Effectful Functions

FunctionTypeDescription
calculateGas(count: number) => Effect<number, InvalidBlobCountError>Calculate blob gas
estimateBlobCount(size: number) => Effect<number, InvalidBlobDataSizeError>Estimate blobs needed
splitData(data: Uint8Array) => Effect<BrandedBlob[], InvalidBlobDataSizeError>Split data into blobs
joinData(blobs: BrandedBlob[]) => Effect<Uint8Array, BlobError>Join blobs into data
toCommitment(blob: BrandedBlob) => Effect<Commitment, KZGError, KZGService>Compute KZG commitment
toProof(blob, commitment) => Effect<Proof, KZGError, KZGService>Compute KZG proof
toVersionedHash(commitment: Commitment) => Effect<VersionedHash, InvalidCommitmentSizeError>Create versioned hash
verify(blob, commitment, proof) => Effect<boolean, KZGError, KZGService>Verify KZG proof
verifyBatch(blobs, commitments, proofs) => Effect<boolean, BlobError>Batch verify (not implemented)

Errors

ErrorDescription
InvalidBlobSizeErrorBlob is not exactly 131072 bytes
InvalidBlobDataSizeErrorData exceeds max blob capacity
InvalidBlobCountErrorBlob count exceeds max per transaction
InvalidBlobLengthPrefixErrorLength prefix in blob is invalid
InvalidCommitmentSizeErrorCommitment is not 48 bytes
InvalidProofSizeErrorProof is not 48 bytes
BlobArrayLengthMismatchErrorArrays have different lengths
BlobNotImplementedErrorOperation not implemented
128KB data blobs for rollup data availability per EIP-4844.