
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
On-chain file storage via chunked transactions for EVM chains.
Store and retrieve files on Ethereum, Base, and Arbitrum using transaction calldata. Includes specialized support for censorship-resistant browser extension distribution.
npm install chunktech viem
For encryption support:
npm install @noble/curves @noble/hashes
import { ChunkTech } from 'chunktech';
import { createWalletClient, http } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
const account = privateKeyToAccount(`0x${process.env.PRIVATE_KEY}`);
const walletClient = createWalletClient({
account,
chain: base,
transport: http(),
});
const ct = new ChunkTech({ walletClient });
// Upload
const result = await ct.upload(fileData, {
onProgress: (sent, total) => console.log(`${sent}/${total}`),
});
// Download
const downloaded = await ct.download(result.txHashes);
Distribute Chrome and Firefox extensions as on-chain inscriptions. The inscription itself is the installer - a self-contained HTML page that fetches extension data from L2 and offers downloads.
┌─────────────────────────────────────────────────────────┐
│ Inscription (Ethereum) │
│ │
│ Self-contained HTML that: │
│ ├── Shows extension info + download buttons │
│ ├── Fetches chunks from Base via RPC │
│ ├── Reassembles + verifies SHA256 │
│ └── Downloads as .zip (Chrome) or .xpi (Firefox) │
│ │
└─────────────────────────────────────────────────────────┘
import { ExtensionUploader } from 'chunktech';
import { createWalletClient, http } from 'viem';
import { base, mainnet } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import { readFileSync } from 'fs';
const account = privateKeyToAccount(`0x${process.env.PRIVATE_KEY}`);
const uploader = new ExtensionUploader({
keyChain: 'ethereum', // Inscription lives here (1 tx)
dataChain: 'base', // Extension data lives here (cheap)
keyWalletClient: createWalletClient({
account,
chain: mainnet,
transport: http(),
}),
dataWalletClient: createWalletClient({
account,
chain: base,
transport: http(),
}),
});
const result = await uploader.upload({
name: 'My Extension',
version: '1.0.0',
developer: 'vitalik.eth',
description: 'A censorship-resistant browser extension',
homepage: 'https://myextension.xyz',
chrome: readFileSync('dist/chrome.zip'),
firefox: readFileSync('dist/firefox.xpi'),
}, {
onProgress: (phase, sent, total) => {
console.log(`${phase}: ${sent}/${total}`);
},
});
console.log('Inscription TX:', result.inscriptionTxHash);
// View at: https://ethscriptions.com/ethscriptions/0x...
The inscription renders as a download page:
╔═══════════════════════════════════════════════════╗
║ My Extension v1.0.0 ║
║ vitalik.eth ║
╚═══════════════════════════════════════════════════╝
A censorship-resistant browser extension
┌─────────────────┐ ┌─────────────────┐
│ Chrome/Brave │ │ Firefox │
│ [Detected] │ │ │
│ [Download] │ │ [Download] │
│ 142 KB │ │ 138 KB │
└─────────────────┘ └─────────────────┘
Installation Instructions:
1. Download the extension
2. Unzip (Chrome) or keep as .xpi (Firefox)
3. Load in developer mode / Install from file
Store bulk data on L2 (cheap), pointer on mainnet (durable):
import { CrossChainUploader } from 'chunktech';
const uploader = new CrossChainUploader({
keyChain: 'ethereum',
dataChain: 'base',
keyWalletClient,
dataWalletClient,
});
const result = await uploader.upload(fileData, {
format: 'html',
title: 'My File',
});
// result.keyTxHash = mainnet inscription (self-loading HTML)
// result.dataTxHashes = Base data chunks
Main class for single-chain uploads.
const ct = new ChunkTech({
walletClient: WalletClient, // viem wallet
publicClient?: PublicClient, // Optional
chain?: Chain, // Auto-detected
rpcUrl?: string, // Custom RPC
});
// Upload
const result = await ct.upload(data, {
encrypt?: boolean,
keys?: EncryptionKeys,
recipients?: Recipient[],
onProgress?: (sent, total) => void,
confirmations?: number,
});
// Download
const result = await ct.download(txHashes, {
keys?: EncryptionKeys,
recipientId?: string,
});
Specialized uploader for browser extensions.
const uploader = new ExtensionUploader({
keyChain: 'ethereum' | 'sepolia',
dataChain: 'base' | 'baseSepolia',
keyWalletClient: WalletClient,
dataWalletClient: WalletClient,
keyRpcUrl?: string,
dataRpcUrl?: string,
});
const result = await uploader.upload({
name: string,
version: string,
developer: string,
description?: string,
homepage?: string,
chrome?: Uint8Array,
firefox?: Uint8Array,
}, {
onProgress?: (phase, sent, total) => void,
confirmations?: number,
});
General-purpose cross-chain uploader with HTML loader.
const uploader = new CrossChainUploader({
keyChain: ChainName,
dataChain: ChainName,
keyWalletClient: WalletClient,
dataWalletClient: WalletClient,
});
const result = await uploader.upload(data, {
format?: 'html' | 'json',
title?: string,
description?: string,
mimeType?: string,
});
import {
// Chunking
chunkData,
encodeChunk,
decodeChunk,
reassembleChunks,
ChunkTracker,
estimateChunks,
// Sending
sendChunk,
sendChunks,
sendChunksParallel,
// Tracking
waitForTransaction,
waitForTransactions,
TransactionMonitor,
// Fetching
fetchChunk,
fetchChunks,
assembleFromHashes,
StreamingAssembler,
// Encryption
generateEncryptionKeys,
deriveKeysFromSignature,
encryptForRecipients,
decryptForRecipient,
} from 'chunktech';
Optional X3DH + AES-256-GCM encryption for private data.
import { generateEncryptionKeys } from 'chunktech';
const myKeys = await generateEncryptionKeys();
// Upload encrypted
await ct.upload(data, {
encrypt: true,
keys: myKeys,
recipients: [
{ id: 'alice', bundle: aliceKeys.bundle },
],
});
// Download encrypted
const result = await ct.download(txHashes, {
keys: myKeys,
recipientId: 'sender',
});
| Chain | ID | Use Case |
|---|---|---|
| Ethereum | 1 | Inscriptions, durability |
| Base | 8453 | Cheap data storage |
| Arbitrum | 42161 | Cheap data storage |
| Sepolia | 11155111 | Testing |
| Base Sepolia | 84532 | Testing |
| Arbitrum Sepolia | 421614 | Testing |
For a 500KB extension on Base:
Chunks: ~15 (at 33KB each)
Cost per chunk: ~$0.002
Total: ~$0.03
+ 1 Ethereum inscription: ~$2-5 (varies with gas)
eth_getTransactionByHash, decode, reassembleCreate standalone HTML pages that fetch, verify, and display on-chain content. Perfect for:
import { readFileSync } from 'fs';
import { createWalletClient, http, toHex } from 'viem';
import { base } from 'viem/chains';
import { createHash } from 'crypto';
const zipData = readFileSync('package.zip');
const base64 = zipData.toString('base64');
const sha256 = createHash('sha256').update(zipData).digest('hex');
const dataUri = `data:application/zip;base64,${base64}`;
const calldata = toHex(new TextEncoder().encode(dataUri));
const hash = await walletClient.sendTransaction({
to: account.address,
data: calldata,
});
console.log(`TX: ${hash}`);
console.log(`SHA256: ${sha256}`);
The viewer fetches from any RPC, verifies SHA256, and displays source:
┌─────────────────────────────────────────┐
│ MyPackage v1.0.0 │
│ │
│ [Download] [Verify On-Chain] │
│ │
│ ┌─────────────────────────────────┐ │
│ │ README │ index.ts │ package.json│ │
│ ├─────────────────────────────────┤ │
│ │ │ │
│ │ // Source code displayed here │ │
│ │ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
Key features:
See skill.md for full implementation details.
MIT
FAQs
On-chain file storage via chunked transactions for EVM chains
We found that chunktech demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.