Framework-agnostic reactive hooks for Walrus decentralized blob storage on Sui.
Walrus DappKit provides a developer-friendly abstraction over the @mysten/walrus SDK with:
- Reactive state management using nanostores (framework-agnostic)
- Progress tracking during multi-node uploads
- Built-in caching for blob reads
- Error handling patterns with typed results
- Framework bindings for React and Vue
| Package | Description | Status |
|---|---|---|
@walrus-dapp-kit/core |
Framework-agnostic core (nanostores) | Ready |
@walrus-dapp-kit/react |
React hooks | Ready |
@walrus-dapp-kit/vue |
Vue 3 composables | Ready |
# Core only (for custom framework integration)
npm install @walrus-dapp-kit/core @mysten/walrus @mysten/sui
# React
npm install @walrus-dapp-kit/react @mysten/walrus @mysten/sui
# Vue 3
npm install @walrus-dapp-kit/vue @mysten/walrus @mysten/suiimport { WalrusProvider, useWriteBlob } from '@walrus-dapp-kit/react';
function App() {
return (
<WalrusProvider config={{ network: 'testnet' }}>
<UploadComponent />
</WalrusProvider>
);
}
function UploadComponent() {
const { writeBlob, isWriting, progress, error } = useWriteBlob();
const handleUpload = async (file: File) => {
const result = await writeBlob({
data: file,
epochs: 3,
deletable: true,
signer, // Your Sui signer
});
console.log('Blob ID:', result.blobId);
};
return (
<div>
<input type="file" onChange={(e) => handleUpload(e.target.files[0])} />
{isWriting && <p>Uploading: {progress}%</p>}
{error && <p>Error: {error.message}</p>}
</div>
);
}<script setup lang="ts">
import { useWriteBlob } from '@walrus-dapp-kit/vue';
const { writeBlob, isWriting, progress, error } = useWriteBlob();
const handleUpload = async (event: Event) => {
const file = (event.target as HTMLInputElement).files?.[0];
if (file) {
const result = await writeBlob({
data: file,
epochs: 3,
deletable: true,
signer, // Your Sui signer
});
console.log('Blob ID:', result.blobId);
}
};
</script>
<template>
<div>
<input type="file" @change="handleUpload" />
<p v-if="isWriting">Uploading: {{ progress }}%</p>
<p v-if="error">Error: {{ error.message }}</p>
</div>
</template>import { createWalrusKit } from '@walrus-dapp-kit/core';
const kit = createWalrusKit({ network: 'testnet' });
// Subscribe to upload state changes
kit.stores.$uploadState.subscribe((state) => {
console.log('Status:', state.status, 'Progress:', state.progress);
});
// Upload a blob
const result = await kit.actions.writeBlob({
data: new Uint8Array([1, 2, 3]),
epochs: 1,
signer,
});Creates a WalrusKit instance with reactive stores and actions.
interface WalrusKitConfig {
network: 'mainnet' | 'testnet';
walrusConfig?: Partial<WalrusClientConfig>;
suiClient?: SuiClient;
}
const kit = createWalrusKit({ network: 'testnet' });| Store | Type | Description |
|---|---|---|
$uploadState |
MapStore<UploadState> |
Current upload state |
$blobCache |
MapStore<Record<string, CachedBlob>> |
Cached blob data |
$isUploading |
ReadableAtom<boolean> |
Whether upload is in progress |
$uploadDuration |
ReadableAtom<number> |
Upload duration in ms |
| Action | Description |
|---|---|
writeBlob(options) |
Upload data to Walrus |
readBlob(options) |
Read blob by ID (with caching) |
clearCache(blobId?) |
Clear blob cache |
resetUploadState() |
Reset upload state to idle |
interface WriteBlobOptions {
data: File | Blob | Uint8Array;
epochs?: number; // Storage duration (default: 1)
deletable?: boolean; // Can be deleted (default: false)
signer: Signer; // Sui transaction signer
}
interface WriteBlobResult {
blobId: string | null;
success: boolean;
error?: Error;
}
type UploadStatus =
| 'idle'
| 'encoding'
| 'registering'
| 'uploading'
| 'certifying'
| 'complete'
| 'error';
interface UploadState {
status: UploadStatus;
progress: number; // 0-100
blobId: string | null;
error: Error | null;
startedAt: number | null;
}| Hook | Description |
|---|---|
useWriteBlob() |
Upload blobs with progress tracking |
useReadBlob(blobId) |
Read blob data with caching |
useUploadState() |
Access global upload state |
| Composable | Description |
|---|---|
useWriteBlob() |
Upload blobs with reactive progress |
useReadBlob(blobId) |
Read blob data with caching |
useUploadState() |
Access global upload state |
+-----------------------------------------------------+
| Your App |
+-----------------------+-----------------------------+
| React Hooks | Vue Composables |
| (useWriteBlob) | (useWriteBlob) |
+-----------------------+-----------------------------+
| @walrus-dapp-kit/core |
| (nanostores - framework agnostic) |
+-----------------------------------------------------+
| @mysten/walrus |
| (low-level Walrus SDK) |
+-----------------------------------------------------+
The official @mysten/walrus SDK provides low-level operations but lacks:
- Progress tracking during multi-node uploads
- Reactive state management for UI updates
- Error handling patterns with typed results
- Caching and optimistic updates
- Framework-specific bindings
This library fills that gap with a framework-agnostic approach, matching the architectural direction of @mysten/dapp-kit-core.
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run examples
pnpm --filter react-demo dev
pnpm --filter vue-demo dev-
useBlobStatus- Check blob certification status -
useStorageCost- Calculate storage costs before upload -
useBlobFlow- Multi-step upload flow management - Svelte bindings
- Solid.js bindings
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
Apache-2.0 (matching Mysten Labs SDKs)