Skip to content

Instantly share code, notes, and snippets.

@tunnckoCore
Created March 14, 2024 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tunnckoCore/04184851e796d9fdab56dbdab7e15328 to your computer and use it in GitHub Desktop.
Save tunnckoCore/04184851e796d9fdab56dbdab7e15328 to your computer and use it in GitHub Desktop.
Ethereum Blobs Utils
import { bytesToString, hexToBytes } from 'viem';
export async function getBlobMeta(hash) {
let result = {};
try {
const res = await fetch(getBlobUrl(hash)).then((x) => x.json());
if (res.error) {
result.error = res.error;
return result;
}
result.data = res.result.data.json;
const { transactionsWithBlocks, versionedHash: blobVersionedHash } = result.data;
delete result.data.transactionsWithBlocks;
delete result.data.versionedHash;
const tx = transactionsWithBlocks[0];
result.data = { ...tx, blobVersionedHash, ...result.data };
return result;
} catch (er) {
result.error = { message: er.message, code: 'FETCHING_BLOB_METADATA_FAILED' };
}
return result;
}
export function getBlobUrl(blobVersionedHash) {
return `https://blobscan.com/api/trpc/blob.getByBlobIdFull?input=${JSON.stringify({
json: { id: blobVersionedHash },
})}`;
}
// NOTE: accept transaction hash, or blob hash (blobVersionedHash) which is the same as transaction hash but with 0x01 prefix
export async function getBlob(hash, options = {}) {
let { withContent = true, withoutInput = false } = { ...options };
withContent = Boolean(withContent);
withoutInput = Boolean(withoutInput);
if (hash.startsWith('0x') && hash.length === 66 && !hash.startsWith('0x01')) {
const getUrl = (txhash) => `https://api.blobscan.com/transactions/` + txhash;
try {
hash = await fetch(getUrl(hash))
.then((x) => x.json())
.then((x) => x.blobs[0]);
} catch (e) {
hash = 'err data';
}
}
if (!hash.startsWith('0x01') && hash.length !== 66) {
return { error: { message: 'invalid blob hash' } };
}
const blobMeta = await getBlobMeta(hash);
if (blobMeta.error) {
console.log('error:', blobMeta.error);
return blobMeta;
}
const input = blobMeta.data.data;
delete blobMeta.data.data;
delete blobMeta.data.size;
if (!withoutInput) {
blobMeta.data.input = input;
}
if (withContent || blobMeta.data.input.startsWith('0x00646174613a')) {
blobMeta.data.content = cleanHexData(input).trim().replace(/\0/g, '');
blobMeta.data.contentSize = blobMeta.data.content.length;
}
return blobMeta;
}
export function cleanHexData(input) {
const u8 = typeof input === 'string' ? hexToBytes(input) : input;
const bytes = [] as any;
u8.forEach((x, i) => {
if (i === 0) return;
if (parseInt(String(x), 16)) {
bytes.push(x);
}
});
return bytesToString(Uint8Array.from(bytes.slice(0, -1)));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment