storewave-sdk
v0.1.4
Published
TypeScript SDK for Walrus Storage Marketplace
Maintainers
Readme
Storewave SDK
TypeScript SDK for the Walrus Storage Marketplace on Sui blockchain. Reserve storage efficiently by combining marketplace listings with direct system purchases.
Features
- Smart Storage Reservation - Automatically optimizes costs by combining marketplace listings with system purchases
- Dry Run Simulation - Validates transactions before execution with automatic fallback
- Auto Coin Management - Automatically fetches and manages WAL token coins
- Type-Safe - Full TypeScript support with comprehensive type definitions
- Universal - Works in both browser (React) and Node.js environments
- Marketplace Integration - List, query, and purchase storage on the marketplace
- Wallet Queries - Easily fetch storage and blob objects from any wallet
Installation
npm install storewave-sdkQuick Start
Initialize SDK
import { WalStorageMarketplace } from 'storewave-sdk';
// Initialize for testnet
const sdk = new WalStorageMarketplace('testnet', {
backendApiUrl: 'http://localhost:3000', // Optional
});Reserve Storage (Simple)
import { Transaction } from '@mysten/sui/transactions';
// Get cost preview first
const cost = await sdk.getReservationCost({
size: 5,
sizeUnit: 'GiB',
durationInEpochs: 100,
});
console.log(`Optimized cost: ${cost.optimizedRoute.totalCostInWal} WAL`);
console.log(`System-only cost: ${cost.systemOnlyRoute.totalCostInWal} WAL`);
console.log(`You save: ${cost.savingsInWal} WAL (${cost.savingsPercentage}%)`);
// Reserve storage
const tx = new Transaction();
const result = await sdk.reserveStorage({
tx,
size: 5,
sizeUnit: 'GiB',
durationInEpochs: 100,
senderAddress: walletAddress,
// WAL coins are automatically fetched!
});
// Sign and execute transaction
await signAndExecuteTransaction({ transaction: result.transaction });API Reference
Constructor
new WalStorageMarketplace(network: 'testnet' | 'mainnet', options?: {
rpcUrl?: string;
backendApiUrl?: string;
})Storage Reservation
getReservationCost()
Get cost preview for storage reservation with marketplace optimization.
const cost = await sdk.getReservationCost({
size: 5,
sizeUnit: 'GiB', // 'bytes' | 'KiB' | 'MiB' | 'GiB' | 'TiB'
durationInEpochs: 100,
});
// Returns:
// {
// optimizedRoute: {
// totalCostInFrost: bigint,
// totalCostInWal: number,
// operations: Operation[],
// usesMarketplace: boolean
// },
// systemOnlyRoute: {
// totalCostInFrost: bigint,
// totalCostInWal: number,
// storageUnits: number
// },
// savingsInFrost: bigint,
// savingsInWal: number,
// savingsPercentage: number,
// recommendation: 'optimized' | 'system-only',
// currentEpoch: number,
// endEpoch: number
// }Key Features:
- Automatically uses current epoch as start epoch
- Compares marketplace vs system-only costs
- Shows potential savings
- Provides optimization recommendation
reserveStorage()
Reserve storage with automatic coin fetching and dry run simulation.
const tx = new Transaction();
const result = await sdk.reserveStorage({
tx,
size: 5,
sizeUnit: 'GiB',
durationInEpochs: 100,
senderAddress: walletAddress,
useOptimization: true, // Default: true
performDryRun: true, // Default: true
});
// Returns:
// {
// transaction: Transaction,
// dryRunResult?: {
// success: boolean,
// usedSystemFallback: boolean,
// error?: string
// },
// estimatedCostInFrost: bigint,
// estimatedCostInWal: number,
// currentEpoch: number,
// endEpoch: number
// }Key Features:
- Automatically fetches WAL coins from wallet
- Automatically uses current epoch
- Performs dry run simulation
- Auto-fallback to system-only if marketplace fails
- Returns ready-to-sign transaction
Wallet Queries
getWalletStorage()
Get storage objects owned by an address.
const storage = await sdk.getWalletStorage({
address: walletAddress,
cursor?: string,
limit?: number, // Default: 20, Max: 100
});
// Returns paginated storage objects
// {
// data: WalrusStorage[],
// nextCursor: string | null,
// hasMore: boolean
// }getWalletBlobs()
Get blob objects owned by an address.
const blobs = await sdk.getWalletBlobs({
address: walletAddress,
cursor?: string,
limit?: number,
});
// Returns paginated blob objectsgetWalBalance()
Get WAL token balance.
const balance = await sdk.getWalBalance(walletAddress);
// Returns balance in FROST (smallest unit)getWalCoins()
Get WAL coin objects.
const coins = await sdk.getWalCoins(walletAddress);
// Returns array of CoinStructMarketplace Operations
getListingsByAddress()
Get marketplace listings for a seller.
const listings = await sdk.getListingsByAddress({
address: sellerAddress,
cursor?: string,
limit?: number,
});
// Returns paginated listingslistStorage()
List storage objects on the marketplace.
const tx = new Transaction();
await sdk.listStorage({
tx,
storageObjectIds: ['0x...', '0x...'],
pricesInWal: [1.5, 2.0],
senderAddress: walletAddress,
});
// Returns modified transactionlistBlobAsStorage()
List blobs as storage (deletes blob first, then lists storage).
const tx = new Transaction();
await sdk.listBlobAsStorage({
tx,
blobObjectIds: ['0x...'],
pricesInWal: [1.5],
senderAddress: walletAddress,
});Utility Functions
getCurrentEpoch()
Get current Walrus epoch.
const epoch = await sdk.getCurrentEpoch();Usage Examples
React Example
import { useState } from 'react';
import { Transaction } from '@mysten/sui/transactions';
import { useCurrentAccount, useSignAndExecuteTransaction } from '@mysten/dapp-kit';
import { WalStorageMarketplace } from 'storewave-sdk';
function StorageReservation() {
const currentAccount = useCurrentAccount();
const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction();
const [cost, setCost] = useState(null);
const sdk = new WalStorageMarketplace('testnet', {
backendApiUrl: 'http://localhost:3000'
});
const handleGetCost = async () => {
const result = await sdk.getReservationCost({
size: 5,
sizeUnit: 'GiB',
durationInEpochs: 100,
});
setCost(result);
};
const handleReserve = async () => {
const tx = new Transaction();
const result = await sdk.reserveStorage({
tx,
size: 5,
sizeUnit: 'GiB',
durationInEpochs: 100,
senderAddress: currentAccount.address,
});
if (result.dryRunResult?.usedSystemFallback) {
console.warn('Used system-only fallback');
}
await signAndExecuteTransaction({ transaction: result.transaction });
};
return (
<div>
<button onClick={handleGetCost}>Get Cost</button>
{cost && (
<div>
<p>Optimized: {cost.optimizedRoute.totalCostInWal} WAL</p>
<p>Savings: {cost.savingsInWal} WAL ({cost.savingsPercentage}%)</p>
</div>
)}
<button onClick={handleReserve}>Reserve Storage</button>
</div>
);
}Node.js Example
import { WalStorageMarketplace } from 'storewave-sdk';
import { Transaction } from '@mysten/sui/transactions';
const sdk = new WalStorageMarketplace('testnet');
// Get wallet storage
const storage = await sdk.getWalletStorage({
address: '0x...',
limit: 20,
});
console.log(`Found ${storage.data.length} storage objects`);
// Get cost preview
const cost = await sdk.getReservationCost({
size: 10,
sizeUnit: 'GiB',
durationInEpochs: 200,
});
console.log(`Cost: ${cost.optimizedRoute.totalCostInWal} WAL`);
console.log(`Savings: ${cost.savingsPercentage}%`);
// Create reservation transaction
const tx = new Transaction();
const result = await sdk.reserveStorage({
tx,
size: 10,
sizeUnit: 'GiB',
durationInEpochs: 200,
senderAddress: '0x...',
});
console.log(`Transaction ready to sign`);Type Definitions
The SDK exports all TypeScript types:
import type {
Network,
SDKOptions,
SizeUnit,
WalrusStorage,
WalrusBlob,
ListedStorage,
PaginatedStorage,
Operation,
OptimizationResult,
} from 'storewave-sdk';Error Handling
The SDK provides custom error classes:
import {
StorewaveError,
InsufficientBalanceError,
NoWalCoinsError,
DryRunFailureError,
BackendError,
ValidationError,
UnsupportedNetworkError,
} from 'storewave-sdk';
try {
await sdk.reserveStorage({...});
} catch (error) {
if (error instanceof NoWalCoinsError) {
console.error('No WAL tokens in wallet');
} else if (error instanceof DryRunFailureError) {
console.error('Transaction would fail:', error.dryRunError);
} else if (error instanceof BackendError) {
console.error('Backend API error:', error.message);
}
}Utility Functions
The SDK also exports utility functions for advanced use cases:
import {
convertToBytes,
convertToStorageUnits,
formatStorageSize,
frostToWal,
walToFrost,
formatWalPrice,
BYTES_PER_UNIT_SIZE,
FROST_PER_WAL,
} from 'storewave-sdk';
// Convert units
const bytes = convertToBytes(5, 'GiB'); // 5368709120
const storageUnits = convertToStorageUnits(bytes); // 5120 MiB
// Format for display
const formatted = formatStorageSize(5368709120n); // "5.00 GiB (5120 storage units)"
// Currency conversions
const wal = frostToWal(1500000000n); // 1.5
const frost = walToFrost(1.5); // 1500000000n
const price = formatWalPrice(1500000000n); // "1.5000"Network Configuration
Testnet (Active)
const sdk = new WalStorageMarketplace('testnet', {
backendApiUrl: 'http://localhost:3000', // or your backend URL
});Mainnet (Placeholder)
const sdk = new WalStorageMarketplace('mainnet', {
backendApiUrl: 'https://api.yourbackend.com',
});Note: Mainnet configuration will be added when the network launches.
Advanced Usage
Custom RPC URL
const sdk = new WalStorageMarketplace('testnet', {
rpcUrl: 'https://your-custom-rpc.com',
backendApiUrl: 'http://localhost:3000',
});Skip Optimization (System-Only)
const result = await sdk.reserveStorage({
tx,
size: 5,
sizeUnit: 'GiB',
durationInEpochs: 100,
senderAddress: walletAddress,
useOptimization: false, // Use system-only route
});Skip Dry Run
const result = await sdk.reserveStorage({
tx,
size: 5,
sizeUnit: 'GiB',
durationInEpochs: 100,
senderAddress: walletAddress,
performDryRun: false, // Skip simulation
});How It Works
Cost Optimization: The SDK queries the backend optimizer API to find the cheapest combination of marketplace listings and system purchases.
Automatic Coin Management: The SDK automatically fetches all WAL coins from your wallet, merges them, and splits them for payments.
Dry Run Simulation: Before executing, the SDK simulates the transaction. If it would fail (e.g., marketplace listings became unavailable), it automatically rebuilds the transaction using system-only purchases.
PTB Construction: The SDK builds a Programmable Transaction Block (PTB) that:
- Buys storage from marketplace listings
- Reserves additional storage from the system if needed
- Fuses multiple storage pieces into one
- Transfers the final storage object to your wallet
Best Practices
- Always get cost preview first to inform users of the price
- Handle dry run failures gracefully with user feedback
- Check for system fallback to notify users when marketplace is unavailable
- Paginate large queries to avoid memory issues
- Use TypeScript for type safety and better developer experience
Contributing
Contributions are welcome! Please ensure:
- Code follows existing patterns
- All types are properly exported
- Examples are updated for new features
- Tests are added for new functionality
License
MIT
Support
For issues and questions:
- GitHub Issues: [repo-link]
- Documentation: [docs-link]
