| name | shelby-sdk |
| description | Build decentralized storage applications with the Shelby Protocol SDK. Use when working with @shelby-protocol/sdk or @shelby-protocol/react. |
Shelby Protocol SDK
The Shelby Protocol SDK enables decentralized blob storage on the Aptos blockchain. This skill covers the core SDK and React hooks.
Cross-Chain Wallet Support
The @shelby-protocol/react hooks support all wallet types through the Signer type:
type Signer = AccountSigner | WalletAdapterSigner;
For Ethereum wallet integration (DAA with SIWE), see the shelby-ethereum-kit skill. For Solana wallet integration (DAA with SIWS), see the shelby-solana-kit skill.
Package Versions
Use the correct versions (as of 2026):
"@shelby-protocol/sdk": "^0.0.9"
"@shelby-protocol/react": "^0.0.5"
"@aptos-labs/ts-sdk": "^5.1.0"
API Response Field Names
When listing blobs with getAccountBlobs(), the response uses:
blobNameSuffix (not name or blobName)
creationMicros (not created_at)
expirationMicros (not expiration)
interface BlobData {
name: string;
blobNameSuffix: string;
size: number;
creationMicros: number;
expirationMicros: number;
}
Installation
pnpm install @shelby-protocol/sdk
pnpm install @shelby-protocol/react @tanstack/react-query
Quick Start - Core SDK (Node.js)
import { ShelbyNodeClient } from "@shelby-protocol/sdk/node";
import { Network, Account } from "@aptos-labs/ts-sdk";
const client = new ShelbyNodeClient({ network: Network.SHELBYNET });
const account = Account.generate();
await client.fundAccountWithShelbyUSD({ address: account.accountAddress, amount: 1_000_000 });
await client.fundAccountWithAPT({ address: account.accountAddress, amount: 1_000_000 });
await client.upload({
blobData: Buffer.from("Hello, Shelby!"),
signer: account,
blobName: "hello.txt",
expirationMicros: Date.now() * 1000 + 86400_000_000,
});
const blob = await client.download({
account: account.accountAddress,
blobName: "hello.txt",
});
const reader = blob.readable.getReader();
const chunks: Uint8Array[] = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
}
const data = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0));
Quick Start - React Hooks
The React hooks work with any wallet type through the Signer interface.
import { ShelbyClientProvider, useAccountBlobs, useUploadBlobs } from "@shelby-protocol/react";
import { ShelbyClient } from "@shelby-protocol/sdk/browser";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useWallet } from "@aptos-labs/wallet-adapter-react";
import { Network } from "@aptos-labs/ts-sdk";
const queryClient = new QueryClient();
const shelbyClient = new ShelbyClient({ network: Network.SHELBYNET });
function App() {
return (
<QueryClientProvider client={queryClient}>
<ShelbyClientProvider client={shelbyClient}>
<StorageComponent />
</ShelbyClientProvider>
</QueryClientProvider>
);
}
function StorageComponent() {
const { account, signAndSubmitTransaction } = useWallet();
const { data: blobs, isLoading } = useAccountBlobs({
account: account?.address,
});
const { mutateAsync: uploadBlobs } = useUploadBlobs({
client: shelbyClient,
});
const handleUpload = async (file: File) => {
const data = new Uint8Array(await file.arrayBuffer());
await uploadBlobs({
signer: { account: account?.address, signAndSubmitTransaction },
blobs: [{ blobData: data, blobName: file.name }],
expirationMicros: Date.now() * 1000 + 86400_000_000,
});
};
return (
<div>
{isLoading ? "Loading..." : `${blobs?.length ?? 0} blobs`}
</div>
);
}
See references/react.md for full React hooks documentation.
Key Concepts
Expiration Time
All blobs have an expiration time in microseconds since Unix epoch:
const expirationMicros = Date.now() * 1000 + 86400_000_000;
const expirationMicros = Date.now() * 1000 + 7 * 24 * 3600 * 1_000_000;
Blob Naming
Blob names can include paths using forward slashes:
await client.upload({
blobName: "images/photos/vacation.jpg",
});
The full blob key is: @{account_address}/{blob_name}
Networks
import { Network } from "@aptos-labs/ts-sdk";
Network.SHELBYNET
Network.LOCAL
API Keys
API keys authenticate your app and manage rate limits. Without one, requests run in "anonymous" mode with lower limits.
Instructions on obtaining an API key: https://docs.shelby.xyz/sdks/typescript/acquire-api-keys
Configuration
interface ShelbyClientConfig {
network: ShelbyNetwork;
apiKey?: string;
deployer?: AccountAddress;
aptos?: AptosSettings;
rpc?: {
baseUrl?: string;
apiKey?: string;
};
indexer?: {
baseUrl?: string;
apiKey?: string;
};
faucet?: string;
gasStationApiKey?: string;
}
Core Operations
Upload
await client.upload({
blobData: Uint8Array,
signer: Account,
blobName: string,
expirationMicros: number,
options?: {
chunksetSizeBytes?: number,
build?: { options?: InputGenerateTransactionOptions },
},
});
Batch Upload
await client.batchUpload({
blobs: [
{ blobData: Buffer.from("File 1"), blobName: "file1.txt" },
{ blobData: Buffer.from("File 2"), blobName: "file2.txt" },
],
expirationMicros: Date.now() * 1000 + 86400_000_000,
signer: account,
});
Download
const blob = await client.download({
account: AccountAddressInput,
blobName: string,
range?: { start: number; end?: number },
});
Delete
const { transaction } = await client.coordination.deleteBlob({
account: signer,
blobName: "file-to-delete.txt",
});
List Blobs
const blobs = await client.coordination.getAccountBlobs({
account: accountAddress,
pagination: { limit: 10, offset: 0 },
});
const files = blobs.map(blob => ({
name: blob.blobNameSuffix,
size: blob.size,
createdAt: new Date(blob.creationMicros / 1000),
expiresAt: new Date(blob.expirationMicros / 1000),
}));
Error Handling
Common errors and how to handle them:
import {
isBlobAlreadyExistsError,
isAccessDeniedError,
isBlobNotFoundError,
isBlobExpiredError,
StaleChannelStateError,
} from "@shelby-protocol/sdk";
try {
await client.upload({ ... });
} catch (error) {
if (isBlobNotFoundError(error.message)) {
}
if (isBlobAlreadyExistsError(error.message)) {
}
if (isAccessDeniedError(error.message)) {
}
if (isBlobExpiredError(error.message)) {
}
if (error instanceof StaleChannelStateError) {
const serverState = error.storedMicropayment;
}
}
HTTP Access
Download files directly via HTTP:
curl https://api.shelbynet.shelby.xyz/shelby/v1/blobs/{account_address}/{blob_name}
Reference Files
For detailed API documentation, see:
references/api-reference.md - Full API documentation for ShelbyClient, ShelbyBlobClient, ShelbyRPCClient
references/react.md - React hooks documentation (works with all wallet types)
references/advanced.md - Micropayments, erasure coding, streaming, low-level operations
references/sdk-feedback.md - Known issues and improvement recommendations for the SDK
Related Skills
- shelby-ethereum-kit - Ethereum wallet integration via Derived Account Abstraction (DAA)
- shelby-solana-kit - Solana wallet integration via Derived Account Abstraction (DAA)