Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ This Turborepo includes the following example applications:

| Name | Description | Path & Links |
| --- | --- | --- |
| `@shelby-protocol/ai-image-generation` | Shelby AI image generation example | [`apps/ai-image-generation`](./apps/ai-image-generation) |
| `@shelby-protocol/cross-chain-accounts` | Shelby cross chain accounts example | [`apps/cross-chain-accounts`](./apps/cross-chain-accounts) |
| `@shelby-protocol/download-example` | An example app to demonstrate downloading blobs using the Shelby SDK | [`apps/download-blob`](./apps/download-blob) |
| `@shelby-protocol/list-example` | An example app to demonstrate listing blobs using the Shelby SDK | [`apps/list-blob`](./apps/list-blob) |
| `@shelby-protocol/upload-example` | An example app to demonstrate uploading blobs using the Shelby SDK | [`apps/upload-blob`](./apps/upload-blob) |

<!-- APPS_TABLE_END -->
Expand Down
15 changes: 15 additions & 0 deletions apps/ai-image-generation/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Shelby Protocol Configuration
NEXT_PUBLIC_SHELBY_API_URL=https://api.shelbynet.shelby.xyz

# AI Service API Keys
OPENAI_API_KEY=your_openai_api_key_here

# Shelby API Key for enhanced rate limits
NEXT_PUBLIC_SHELBY_API_KEY=your_shelby_api_key_here

# Aptos API Key for enhanced rate limits
NEXT_PUBLIC_APTOS_API_KEY=your_aptos_api_key_here


NEXT_PUBLIC_SPONSOR_ACCOUNT_ADDRESS=0x...
NEXT_PUBLIC_SPONSOR_PRIVATE_KEY=ed25519-priv-0x...
151 changes: 151 additions & 0 deletions apps/ai-image-generation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Shelby AI Image Generation - Decentralized AI Artifact Registry

This demo demonstrates how **Shelby can serve as the data and provenance layer for AI systems**. Every AI inference run produces verifiable, on-chain artifacts that are immutable, attributable, and accessible via Shelby's decentralized network.

Unlike traditional cloud storage solutions, this application showcases Shelby as a **"Web3 S3" specifically designed for AI workloads** - where AI-generated content lives permanently on-chain with cryptographic provenance, not trapped in centralized systems.

## 🧠 What Makes This AI-Focused

This isn't just file storage - it's an **AI artifact registry** that demonstrates:

### **AI Provenance & Authenticity**

- Every generated image is cryptographically tied to your Aptos wallet address
- Immutable storage ensures AI outputs can't be tampered with after creation
- Full traceability from prompt → model → output → storage

### **Decentralized AI Infrastructure**

- **Compute Layer**: OpenAI DALL-E 3 (external AI service)
- **Storage Layer**: Shelby protocol (decentralized, incentivized network)
- **Provenance Layer**: Aptos blockchain (immutable ownership records)

### **AI-Specific Metadata**

Each generated image includes structured metadata stored alongside:

```json
{
"prompt": "A futuristic city at sunset",
"engine": "openai",
"model": "dall-e-3",
"createdAt": 1698765432000,
"creator": "0x1234...abcd",
"image": {
"url": "https://api.shelbynet.shelby.xyz/shelby/v1/blobs/0x745...123/images/...."
},
"blobName": "images/A futuristic city at sunset_82p.png"
}
```

## 🏗️ Architecture: Modular Compute-Storage Separation

```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐
│ AI Compute │ │ Shelby Storage │ │ Aptos Blockchain │
│ (DALL-E 3) │───▶│ (Artifacts) │───▶│ (Provenance) │
│ │ │ │ │ │
│ • Image Gen │ │ • Immutable │ │ • Ownership │
│ • Model Runs │ │ • Decentralized │ │ • Commitments │
│ • Stateless │ │ • Auditable │ │ • Expiration │
└─────────────────┘ └──────────────────┘ └─────────────────────┘
```

This architecture proves that **AI models can run anywhere, but their data, artifacts, and provenance should live in a decentralized, verifiable layer**.

## 🔥 Why This Matters for AI

### **Verifiable AI Outputs**

- Prove ownership of AI-generated content
- Combat deepfakes with cryptographic authenticity
- Enable model output traceability and reproducibility

### **Open AI Infrastructure**

- AI artifacts aren't locked in vendor silos (AWS, Google Cloud)
- Decentralized storage with incentivized uptime guarantees
- Permissionless access to AI-generated data

### **Future-Ready for Verifiable Compute**

- Today: External AI + Shelby storage
- Tomorrow: Shelby-native AI compute in TEEs with zero-knowledge proofs
- Same artifact storage pattern scales to fully decentralized AI pipelines

## Getting Started

### Prerequisites

- `node` and `pnpm`
- Shelby and Aptos API keys. For best performance, you are encouraged to generate an API key so your app will not hit the rate limit.
- Head to [Geomi](https://geomi.dev/)
- Generate an API key for `shelbynet` and add it to the `.env` file as `NEXT_PUBLIC_SHELBY_API_KEY=<my-api-key>`
- Generate an API key for `devnet` and add it to the `.env` file as `NEXT_PUBLIC_APTOS_API_KEY=<my-api-key>`
- OpenAI API Key. Head to [OpenAI Platform](https://platform.openai.com/api-keys) to generate an API Key and add it to the `.env` file as `OPENAI_API_KEY=<my-api-key>`

Create an `.env` file by copying the `.env.example` file and fill out the required variables.

```bash
cp .env.example .env
```

Then install dependencies and run the dapp locally

```bash
pnpm install
pnpm run dev
```

Open [http://localhost:3001](http://localhost:3001) with your browser to see the result.

## 🛠️ Technical Implementation

### **AI Generation Pipeline**

```typescript
// 1. Generate image via OpenAI API
const imageBuffer = await generateImage(prompt);

// 2. Create cryptographic commitments
const commitments = await generateCommitments(provider, imageBuffer);

// 3. Register blob on Aptos blockchain
const payload = ShelbyBlobClient.createRegisterBlobPayload({
account: account.address,
blobName: `images/${blobName}.png`,
blobMerkleRoot: commitments.blob_merkle_root,
// ... other metadata
});

// 4. Upload to Shelby's decentralized network
await shelbyClient.rpc.putBlob({
account: account.address,
blobName: imageName,
blobData: new Uint8Array(imageBuffer),
});
```

### **Key Features**

- **Cross-chain wallet support** (Aptos native + Solana + EVM wallets via sponsored transactions)
- **Metadata co-location** (JSON metadata stored alongside each image)
- **Gallery view** (All your AI artifacts in one place)
- **Explorer integration** (Direct links to Shelby blob explorer)

### **What You'll Experience:**

1. **Connect Wallet** - Your Aptos address becomes your AI identity
2. **Generate Image** - AI creates content using your prompt
3. **Store on Shelby** - Image + metadata uploaded to decentralized storage
4. **Verify Provenance** - View your artifacts in Shelby Explorer with full ownership proof

## 🔮 What This Proves About Shelby

| **Capability** | **Demonstrated** |
| ------------------------------ | ------------------------------------------------------ |
| **AI Artifact Storage** | ✅ Images stored & served decentralized |
| **Replaces S3/IPFS for AI** | ✅ Fast reads, permanent storage, verifiable ownership |
| **Compute-Storage Separation** | ✅ Model runs anywhere, results live on Shelby |
| **Provenance & Authenticity** | ✅ Each blob cryptographically tied to creator |
| **Future-Ready Architecture** | ✅ Same pattern works for Shelby-native compute |
58 changes: 58 additions & 0 deletions apps/ai-image-generation/app/api/generate-image/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { type NextRequest, NextResponse } from "next/server";
import OpenAI from "openai";

const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? "";

const openaiClient = new OpenAI({
apiKey: OPENAI_API_KEY,
});

async function genWithOpenAI(prompt: string): Promise<Buffer> {
if (!OPENAI_API_KEY) throw new Error("Set OPENAI_API_KEY");

const response = await openaiClient.images.generate({
model: "dall-e-3",
prompt: prompt,
size: "1024x1024",
response_format: "b64_json",
n: 1,
});

if (!response.data) {
throw new Error("No image data received from OpenAI");
}

const imageData = response.data[0];

if (!imageData.b64_json) {
throw new Error("No base64 image data received from OpenAI");
}

return Buffer.from(imageData.b64_json, "base64");
}

export async function POST(request: NextRequest) {
try {
const body = await request.json();
const prompt = String(body?.prompt || "");

if (!prompt) {
return NextResponse.json({ error: "prompt required" }, { status: 400 });
}

const imageBuffer = await genWithOpenAI(prompt);

return new NextResponse(new Uint8Array(imageBuffer), {
headers: {
"Content-Type": "image/png",
"Content-Length": imageBuffer.length.toString(),
},
});
} catch (e: unknown) {
console.error(e);
return NextResponse.json(
{ error: e instanceof Error ? e.message : "generation failed" },
{ status: 500 },
);
}
}
Binary file added apps/ai-image-generation/app/favicon.ico
Binary file not shown.
Binary file not shown.
Binary file added apps/ai-image-generation/app/fonts/GeistVF.woff
Binary file not shown.
1 change: 1 addition & 0 deletions apps/ai-image-generation/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "@shelby-protocol/ui/globals.css";
36 changes: 36 additions & 0 deletions apps/ai-image-generation/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Toaster } from "@shelby-protocol/ui/components";
import localFont from "next/font/local";
import { WalletProvider } from "@/components/WalletProvider";
import "./globals.css";
import type { Metadata } from "next";

const geistSans = localFont({
src: "./fonts/GeistVF.woff",
variable: "--font-geist-sans",
});
const geistMono = localFont({
src: "./fonts/GeistMonoVF.woff",
variable: "--font-geist-mono",
});

export const metadata: Metadata = {
title: "Shelby AI Image Generation Example",
description: "An AI image generation example using Shelby protocol",
};

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${geistMono.variable}`}>
<WalletProvider>
{children}
<Toaster />
</WalletProvider>
</body>
</html>
);
}
35 changes: 35 additions & 0 deletions apps/ai-image-generation/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use client";

import { useState } from "react";
import { GeneratedImages } from "@/components/GeneratedImages";
import { Header } from "@/components/Header";
import { ImageGenerator } from "@/components/ImageGenerator";

export default function Home() {
const [refreshTrigger, setRefreshTrigger] = useState(0);

const handleImageGenerated = () => {
setRefreshTrigger((prev) => prev + 1);
};

return (
<div className="min-h-screen p-5">
<Header />

{/* Main Content */}
<main className="flex-1">
<div className="max-w-4xl mx-auto space-y-6">
<div className="text-center">
<h1 className="text-4xl font-bold mb-4">AI Image Generation</h1>
<p className="text-lg text-muted-foreground">
Generate images using AI and store them on the Shelby protocol
</p>
</div>

<ImageGenerator onImageGenerated={handleImageGenerated} />
<GeneratedImages refreshTrigger={refreshTrigger} />
</div>
</main>
</div>
);
}
20 changes: 20 additions & 0 deletions apps/ai-image-generation/components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "../../packages/ui/src/styles/globals.css",
"baseColor": "neutral",
"cssVariables": true
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"hooks": "@/hooks",
"lib": "@/lib",
"utils": "@shelby-protocol/ui/lib/utils",
"ui": "@shelby-protocol/ui/components"
}
}
Loading