ethstorage-sdk
Version:
eip-4844 blobs upload sdk
264 lines (250 loc) • 10.7 kB
text/typescript
import { ethers, Contract } from 'ethers';
declare const EthStorageAbi: readonly string[];
declare const FlatDirectoryAbi: readonly string[];
declare const ETHSTORAGE_MAPPING: Record<number, string>;
declare const BLOB_SIZE: number;
declare const OP_BLOB_DATA_SIZE: number;
declare enum DecodeType {
RawData = 0,
PaddingPer31Bytes = 1,
OptimismCompact = 2
}
declare const BLOB_COUNT_LIMIT: number;
declare const MAX_BLOB_COUNT: number;
declare enum UploadType {
Undefined = 0,
Calldata = 1,
Blob = 2
}
/**
* eth_call consumes gas, so we need to estimate the maximum number of chunks based on a 30 million gas limit.
* Additionally, we need to reserve a portion of the gas for the cost of the request parameters (which can vary dynamically).
*/
declare const MAX_CHUNKS: number;
declare const DUMMY_VERSIONED_COMMITMENT_HASH = "0x01f32ebe6ad26adca597cdb198f041f5d96fc197e3de72e299e86fbf1f5817c8";
declare const FlatDirectoryBytecode: string;
declare const FLAT_DIRECTORY_CONTRACT_VERSION_1_0_0: string;
declare const FLAT_DIRECTORY_CONTRACT_VERSION_1_1_0: string;
interface NodeFile {
isNodeJs: boolean;
size: number;
start: number;
end: number;
slice(start: number, end: number): NodeFile;
arrayBuffer(): Promise<ArrayBuffer>;
text(): Promise<string>;
}
type BufferLike = Uint8Array;
type FileLike = File | NodeFile;
type ContentLike = BufferLike | FileLike;
interface SDKConfig {
rpc?: string;
privateKey?: string;
ethStorageRpc?: string;
address?: string;
}
interface UploadCallback {
onProgress: (currentChunk: number, totalChunks: number, isChange: boolean) => void;
onFail: (error: Error) => void;
onFinish: (totalUploadChunks: number, totalUploadSize: number, totalCost: bigint) => void;
onTransactionSent?: (txHash: string, chunkIds: number[] | number) => void;
}
interface DownloadCallback {
onProgress: (currentChunk: number, totalChunks: number, chunkData: Uint8Array) => void;
onFail: (error: Error) => void;
onFinish: () => void;
}
interface EstimateGasRequest {
key: string;
content: ContentLike;
type: UploadType;
gasIncPct?: number;
chunkHashes?: string[];
}
interface UploadRequest extends EstimateGasRequest {
isConfirmedNonce?: boolean;
callback: Partial<UploadCallback>;
}
interface CostEstimate {
storageCost: bigint;
gasCost: bigint;
}
interface TxCost {
normalGasCost: bigint;
blobGasCost: bigint;
}
interface UploadResult {
txCost: TxCost;
success: boolean;
}
interface FileBatch {
name: string;
chunkIds: number[];
}
interface UploadDetails {
fileMode: number;
oldChunkCount: number;
cost: bigint;
gasFeeData?: ethers.FeeData;
maxFeePerBlobGas?: bigint;
}
interface ChunkCountResult {
key: string;
chunkCount: number;
}
interface ChunkHashResult {
name: string;
chunkId: number;
hash: string;
}
declare const stringToHex: (s: string) => string;
declare function getChainId(rpc: string): Promise<number>;
declare function getContentChunk(content: ContentLike, start: number, end: number): Promise<Uint8Array<ArrayBuffer>>;
declare function isBuffer(content: ContentLike): content is BufferLike;
declare function isFile(content: ContentLike): content is FileLike;
declare function isNodejs(): boolean;
declare function computeVersionedCommitmentHash(commitment: Uint8Array): Uint8Array;
declare function convertToEthStorageHash(commitment: Uint8Array): string;
declare function convertToEthStorageHashes(commitments: Uint8Array[]): string[];
declare function copy(des: Uint8Array, desOff: number, src: Uint8Array, srcOff: number): number;
declare function calcTxCost(receipt: ethers.TransactionReceipt | null): TxCost;
declare function encodeOpBlobs(data: Uint8Array): Uint8Array[];
declare function encodeOpBlob(data: Uint8Array): Uint8Array;
declare const EMPTY_BLOB_CONSTANTS: {
DATA: Uint8Array<ArrayBuffer>;
COMMITMENT: Uint8Array<ArrayBufferLike>;
};
type BuildBlobTxParams = {
baseTx: ethers.TransactionRequest;
blobs: Uint8Array[];
commitments?: Uint8Array[];
gasIncPct?: number;
};
declare class BlobUploader {
#private;
constructor(rpc: string, privateKey: string);
getBlobGasPrice(): Promise<bigint>;
getGasPrice(): Promise<ethers.FeeData>;
computeCommitmentsForBlobs(blobs: Uint8Array[]): Promise<Uint8Array[]>;
computeEthStorageHashesForBlobs(blobs: Uint8Array[]): Promise<string[]>;
getTransactionResult(hash: string): Promise<UploadResult>;
/**
* Computes KZG commitments and cell proofs for the given blobs,
* then constructs an EIP-4844 transaction request with the corresponding fields.
*/
buildBlobTx(params: BuildBlobTxParams): Promise<ethers.TransactionRequest>;
/**
* Sends a transaction without using the Mutex lock.
*/
sendTx(tx: ethers.TransactionRequest): Promise<ethers.TransactionResponse>;
/**
* Sends a transaction using the Mutex lock to ensure sequential submission.
*/
sendTxLock(tx: ethers.TransactionRequest, confirmNonce: boolean): Promise<ethers.TransactionResponse>;
/**
* Cleans up resources, specifically terminating the KZG WASM instance.
*/
close(): Promise<void>;
}
declare function getUploadInfo(contract: Contract, hexName: string): Promise<UploadDetails>;
declare function getChunkCounts(contract: Contract, batch: string[]): Promise<ChunkCountResult[]>;
declare function getChunkHashes(contract: Contract, batch: FileBatch[]): Promise<ChunkHashResult[]>;
declare function stableRetry<T>(fn: (...args: unknown[]) => Promise<T>, ...args: unknown[]): Promise<T>;
type index_BlobUploader = BlobUploader;
declare const index_BlobUploader: typeof BlobUploader;
declare const index_EMPTY_BLOB_CONSTANTS: typeof EMPTY_BLOB_CONSTANTS;
declare const index_calcTxCost: typeof calcTxCost;
declare const index_computeVersionedCommitmentHash: typeof computeVersionedCommitmentHash;
declare const index_convertToEthStorageHash: typeof convertToEthStorageHash;
declare const index_convertToEthStorageHashes: typeof convertToEthStorageHashes;
declare const index_copy: typeof copy;
declare const index_encodeOpBlob: typeof encodeOpBlob;
declare const index_encodeOpBlobs: typeof encodeOpBlobs;
declare const index_getChainId: typeof getChainId;
declare const index_getChunkCounts: typeof getChunkCounts;
declare const index_getChunkHashes: typeof getChunkHashes;
declare const index_getContentChunk: typeof getContentChunk;
declare const index_getUploadInfo: typeof getUploadInfo;
declare const index_isBuffer: typeof isBuffer;
declare const index_isFile: typeof isFile;
declare const index_isNodejs: typeof isNodejs;
declare const index_stableRetry: typeof stableRetry;
declare const index_stringToHex: typeof stringToHex;
declare namespace index {
export { index_BlobUploader as BlobUploader, index_EMPTY_BLOB_CONSTANTS as EMPTY_BLOB_CONSTANTS, index_calcTxCost as calcTxCost, index_computeVersionedCommitmentHash as computeVersionedCommitmentHash, index_convertToEthStorageHash as convertToEthStorageHash, index_convertToEthStorageHashes as convertToEthStorageHashes, index_copy as copy, index_encodeOpBlob as encodeOpBlob, index_encodeOpBlobs as encodeOpBlobs, index_getChainId as getChainId, index_getChunkCounts as getChunkCounts, index_getChunkHashes as getChunkHashes, index_getContentChunk as getContentChunk, index_getUploadInfo as getUploadInfo, index_isBuffer as isBuffer, index_isFile as isFile, index_isNodejs as isNodejs, index_stableRetry as stableRetry, index_stringToHex as stringToHex };
}
declare class EthStorage {
#private;
static create(config: SDKConfig): Promise<EthStorage>;
estimateCost(key: string, data: Uint8Array): Promise<CostEstimate>;
write(key: string, data: Uint8Array): Promise<{
hash: string;
success: boolean;
}>;
read(key: string, decodeType?: DecodeType, address?: string): Promise<Uint8Array>;
writeBlobs(keys: string[], dataBlobs: Uint8Array[]): Promise<{
hash: string;
success: boolean;
}>;
close(): Promise<void>;
}
declare class FlatDirectory {
#private;
isSupportBlob: boolean;
/**
* Private constructor - use create() factory method
*/
private constructor();
static create(config: SDKConfig): Promise<FlatDirectory>;
/**
* Enable or disable logging
* @param value - true to enable logging, false to disable
*/
setLogEnabled(value: boolean): void;
/**
* Deploy a new FlatDirectory contract
* @returns Contract address if successful, null otherwise
*/
deploy(): Promise<string | null>;
/**
* Set a file as the default file
* @param filename - Name of the file to set as default
* @returns true if successful, false otherwise
*/
setDefault(filename: string): Promise<boolean>;
/**
* Remove a file from the contract
* @param key - File key to remove
* @returns true if successful, false otherwise
*/
remove(key: string): Promise<boolean>;
/**
* Download a file from the contract
* @param key - File key to download
* @param cb - Download callback object
*/
download(key: string, cb?: DownloadCallback): Promise<void>;
/**
* Fetch chunk hashes for multiple files
* @param keys - Array of file keys
* @returns Object mapping file keys to their chunk hashes
*/
fetchHashes(keys: string[]): Promise<Record<string, string[]>>;
/**
* Estimate cost for uploading a file
* @param request - Upload request details
* @returns Cost estimation object
*/
estimateCost(request: EstimateGasRequest): Promise<CostEstimate>;
/**
* Upload a file to the contract
* @param request - Upload request details
* @throws Error if upload fails
*/
upload(request: UploadRequest): Promise<void>;
/**
* Close the blob uploader and release resources
*/
close(): Promise<void>;
}
export { BLOB_COUNT_LIMIT, BLOB_SIZE, type BufferLike, type ChunkCountResult, type ChunkHashResult, type ContentLike, type CostEstimate, DUMMY_VERSIONED_COMMITMENT_HASH, DecodeType, type DownloadCallback, ETHSTORAGE_MAPPING, type EstimateGasRequest, EthStorage, EthStorageAbi, FLAT_DIRECTORY_CONTRACT_VERSION_1_0_0, FLAT_DIRECTORY_CONTRACT_VERSION_1_1_0, type FileBatch, type FileLike, FlatDirectory, FlatDirectoryAbi, FlatDirectoryBytecode, MAX_BLOB_COUNT, MAX_CHUNKS, type NodeFile, OP_BLOB_DATA_SIZE, type SDKConfig, type TxCost, type UploadCallback, type UploadDetails, type UploadRequest, type UploadResult, UploadType, index as utils };