A modern, decentralized file upload application powered by User-Controlled Authorization Networks (UCANs) and the Storacha Network. This project demonstrates how to build secure, token-free file storage using capability-based authorization instead of traditional API keys.
- Overview
- Key Features
- Architecture
- Project Structure
- Getting Started
- How It Works
- UCAN Flow Diagram
- Component Architecture
- Contributing
- Resources
- License
UCAN Upload Wall is a demonstration of decentralized file storage using User-Controlled Authorization Networks (UCANs). Instead of relying on centralized API keys or bearer tokens, this application uses cryptographic capabilities to securely delegate upload permissions.
Files uploaded through this interface are stored on Filecoin via the Storacha Network, ensuring permanent, verifiable, and decentralized storage.
- No API Keys: Authorization is handled through UCAN proofs
- Decentralized: Files are stored on Filecoin via Storacha
- Capability-Based: Fine-grained permission delegation
- Content Addressing: Each file gets a unique CID (Content Identifier)
- Cryptographically Secure: All permissions are verified through UCAN chains
- 🎯 Drag & Drop Upload: Intuitive file upload interface
- 🔗 Content Addressing: Every file gets a unique CID
- 📋 Upload History: Track all uploaded files
- 📎 Easy Sharing: Copy CID or view files via IPFS gateway
- 🎨 Modern UI: Clean, responsive design with Tailwind CSS
- ⚡ Fast: Built with Vite for optimal performance
- 🔒 UCAN Authorization: Secure, token-free authentication
- 📱 Responsive: Works seamlessly on all devices
┌─────────────────────────────────────────────────────────────┐
│ User Browser │
│ (React + Vite App) │
└──────────────────────┬──────────────────────────────────────┘
│
│ HTTP Request (FormData)
▼
┌─────────────────────────────────────────────────────────────┐
│ Backend Server │
│ (Express + TypeScript) │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ UCAN Agent (DID + Private Key) │ │
│ └──────────────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Delegation Proof (space-proof.car) │ │
│ │ Grants upload capabilities to agent │ │
│ └──────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────────┘
│
│ UCAN Invocation
▼
┌─────────────────────────────────────────────────────────────┐
│ Storacha Network │
│ │
│ ┌────────────────────────────────────┐ │
│ │ 1. Validate UCAN Proof │ │
│ │ 2. Verify Delegation Chain │ │
│ │ 3. Check Capabilities │ │
│ └────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────────┘
│
│ Store File
▼
┌─────────────────────────────────────────────────────────────┐
│ Filecoin Storage │
│ (Permanent, Decentralized) │
│ │
│ Returns: CID (Content Identifier) │
└─────────────────────────────────────────────────────────────┘
┌──────────────┐
│ User Space │ (Your Storacha namespace)
│ (DID:key) │
└──────┬───────┘
│
│ Creates Delegation
│ (storacha space create)
▼
┌─────────────────────────────────────────┐
│ UCAN Delegation Proof (.car) │
│ │
│ Capabilities: │
│ - space/blob/add │
│ - store/add │
│ - upload/add │
│ │
│ Audience: Backend Agent DID │
│ Expiration: Time-limited │
└──────────────┬──────────────────────────┘
│
│ Agent Reads Proof
▼
┌─────────────────────────────────────────┐
│ Backend Agent │
│ Authorized to Upload on Your Behalf │
└──────────────┬──────────────────────────┘
│
│ Invokes Upload
▼
┌─────────────────────────────────────────┐
│ Storacha Network │
│ Validates UCAN Chain & Executes │
└─────────────────────────────────────────┘
ucan-upload-wall/
├── src/
│ ├── components/
│ │ ├── Alert.tsx # Toast notifications
│ │ ├── FileList.tsx # Display uploaded files
│ │ ├── Header.tsx # App header
│ │ └── UploadZone.tsx # Drag & drop upload UI
│ │
│ ├── hooks/
│ │ └── useFileUpload.ts # Upload logic & state
│ │
│ ├── types/
│ │ └── upload.ts # TypeScript interfaces
│ │
│ ├── App.tsx # Main application
│ ├── main.tsx # Entry point
│ └── index.css # Global styles
│
├── public/ # Static assets
├── dist/ # Production build
│
├── .env # Environment variables
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
├── tailwind.config.js # Tailwind config
├── vite.config.ts # Vite config
└── README.md # This file
- Node.js ≥ 18.x
- npm or yarn
- Backend server running on
http://localhost:8787
- Clone the repository
git clone https://github.com/Fatumayattani/ucan-upload-wall.git
cd ucan-upload-wallInstall all required packages for the frontend.
npm installCreate a .env file in the root directory of your backend project and add the following values.
These connect your local server to your Storacha Space.
PORT=8080
KEY=PASTE_THE_PRIVATE_KEY_FROM_key_create
PROOF=PASTE_THE_BASE64_FROM_delegation_create
SPACE_DID=PASTE_THE_SPACE_DID_FROM_space_createFirst, run the frontend (from the /web folder):
npm run devThis starts the UI on http://localhost:5173.
Then, open a new terminal window and run the backend (from the /server folder):
npm install
npm run devThe backend will run on http://localhost:8787.
The user drags and drops a file or clicks to select one from their device.
The useFileUpload hook prepares the file and sends it to the backend via FormData:
const formData = new FormData();
formData.append('file', file);
const response = await fetch('http://localhost:8787/api/upload', {
method: 'POST',
body: formData,
});The backend server:
- Receives the file
- Loads the UCAN delegation proof
- Creates a Storacha client with the proof
- Invokes the upload capability
- Returns the CID (Content Identifier)
Storacha Network validates:
- The UCAN proof signature
- The delegation chain
- The requested capability (upload permission)
- The proof expiration
If validated, the file is:
- Stored on Filecoin
- Assigned a unique CID
- Made available via IPFS gateways
The frontend receives the CID and:
- Displays it in the file list
- Provides copy and view options
- Shows success notification
sequenceDiagram
participant User
participant Frontend
participant Backend
participant Storacha
participant Filecoin
User->>Frontend: Select/Drop File
Frontend->>Frontend: Validate File
Frontend->>Backend: POST /api/upload (FormData)
Backend->>Backend: Load UCAN Proof
Backend->>Backend: Initialize Storacha Client
Backend->>Storacha: Invoke Upload (with UCAN)
Storacha->>Storacha: Validate UCAN Chain
Storacha->>Storacha: Verify Capabilities
Storacha->>Filecoin: Store File
Filecoin-->>Storacha: Return CID
Storacha-->>Backend: Upload Success + CID
Backend-->>Frontend: { ok: true, cid: "bafybeig..." }
Frontend->>Frontend: Add to Upload List
Frontend->>User: Show Success + CID
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- React Documentation
- Vite Documentation
- TypeScript Documentation
- Tailwind CSS
- IPFS Documentation
- Filecoin Documentation
This project is licensed under the MIT License - see the LICENSE file for details.
| Name | Role | GitHub |
|---|---|---|
| Fatuma Yattani | Lead Developer | @Fatumayattani |
| Storacha PLDG Community | Support & Guidance | - |
- Storacha Team for building an amazing UCAN-based storage platform
- UCAN Working Group for the specification
- IPFS & Filecoin communities for decentralized storage infrastructure
Here is a detailed walkthrough of the project on Medium: