Sitemap
FIL-B

FIL-B

FIL-B is the public goods developer experience (DX) team for the Filecoin ecosystem, helping builders successfully develop on-chain solutions.

Building a Decentralized File Storage App with Filecoin and Synapse SDK

7 min readMar 4, 2026

--

Filecoin Onchain Cloud dApp: A Comprehensive Guide

This guide provides a deep dive into the Filecoin Onchain Cloud dApp, a starter kit for building decentralized storage applications on Filecoin. This dApp showcases the process of building a practical application on Filecoin, enabling users to easily store and manage files on a decentralized storage network using USDFC payments. Using the Synapse SDK, the dApp enables users to upload, manage, and pay for decentralized storage seamlessly. This article will explore its architecture, key features, and how to use them.

Press enter or click to view image in full size

Introduction

The Filecoin Onchain Cloud dApp is a Next.js application designed to simplify the process of storing and managing files on the Filecoin network. It offers a user-friendly interface and abstracts away much of the complexity involved in interacting with decentralized storage systems. Key features include:

  • Multi-file, multi-copy uploads with standard, Filecoin Beam (CDN addon), and Filecoin Pin (IPFS addon) modes.
  • Store-pull-commit workflow for efficient bandwidth utilization.
  • USDFC payments with auto-topup and balance sufficiency checks.
  • Session keys for delegated signing and seamless multi-operation workflows.
  • Real-time dashboard with balances, storage metrics, and cost breakdowns.
  • Dataset and file browsing with CID validation and delete functionality.

Read more on Filecoin Onchain Cloud here.

Architecture

The dApp follows a well-defined architecture with clear separation of concerns. The project structure is organized into several layers, each serving a specific purpose.

Press enter or click to view image in full size

The separation of concerns into distinct layers (Pages, Components, Hooks, Libs, Providers) allows for a more modular and maintainable codebase. Data fetching and side effects are encapsulated within hooks, while pure transformations reside in libs.

Provider Stack

The provider stack in src/app/layout.tsx sets up the necessary context for the entire application.

Press enter or click to view image in full size

This stack ensures that web3 connection, data fetching, storage configuration, and session management are available throughout the app.

File Map

The project’s file structure is organized as follows:

src/
├── app/ # Next.js App Router (Routes & Layouts)
│ ├── layout.tsx # Root layout with Provider Stack
│ ├── page.tsx # Dashboard (/)
│ ├── upload/ # /upload route
│ │ ├── page.tsx
│ │ └── types.ts # Route-specific types (UploadMode, Phase, etc.)
│ ├── datasets/ # /datasets route (?id= logic)
│ │ ├── page.tsx
│ │ └── components/ # Dataset-specific UI (Card, Detail, Row)
│ └── files/ # /files route (Cross-dataset view)
│ ├── page.tsx
│ └── components/ # Files-specific UI
├── components/ # Shared UI Components
│ ├── ui/ # shadcn/Radix primitives & atomic components
│ ├── layout/ # Navbar, Footer, WalletGuard, WalletMenu
│ ├── home/ # BalanceCards, StorageDashboard
│ ├── storage/ # PiecePreview, CostBreakdown, FilePreview
│ ├── pay/ # Deposit, Withdraw components
│ └── uploader.tsx # Main Orchestrator Component
│ ├── upload-controls/ # Dropzone, Mode/Copy selectors
│ ├── upload-results/ # Result cards
│ └── upload-status-panel/# Progress timeline
├── hooks/ # Logic & State Orchestration
│ ├── use-upload.ts # CDN/Standard upload orchestrator
│ ├── use-pin-upload.ts # IPFS/Filecoin pinning logic
│ ├── use-balances.ts # FIL/USDFC & storage metrics
│ ├── use-storage-overview.ts # Dashboard data aggregator
│ └── use-download.ts # CID validation & MIME detection
├── lib/ # Stateless Utilities & Business Logic
│ ├── filecoin-pin/ # Specialized Filecoin logic (CAR builder)
│ ├── synapse-client.ts # API Client factory with Session Keys
│ ├── datasets.ts # Data transformers & cost computations
│ ├── decimal.ts # Precision math for storage costs
│ ├── query-keys.ts # Centralized React Query key factory
│ └── format.ts # Unit formatting (Capacity/Currency)
└── providers/ # Context & State Wrappers
├── web3-provider/ # Wagmi + RainbowKit + TanStack Query
├── wallet/ # Wallet connection + Zustand store
├── session-key/ # Session key lifecycle management
└── storage-config/ # LocalStorage + Zustand preferences

Key Features

Session Keys

Session keys provide a delegated signing system that allows users to perform multiple upload, delete, and dataset operations without needing to confirm each transaction in their wallet. This is particularly useful for multi-file, multi-copy workflows.

Lifecycle:

1. getSynapseClient(), checks for a stored session key the function is available in src/lib/synapse-client.ts.
2. If a key is missing, the app prompts the user to create one.
3. SessionKey.login(walletClient, { address, expiresAt }) creates a key with DefaultFwssPermissions.
4. The key is saved to a Zustand store, persisted in localStorage, and scoped per `address + chainId`.
5. Users can extend (1–31 days) or revoke the key at any time.

Code Snippet (src/lib/synapse-client.ts):

import { SessionKey } from '@filoz/synapse-core';
async function getSynapseClient(withSession?: boolean) {
// …
const sessionData = await getSessionData(address, chainId);
if (withSession && !sessionData) {
// Prompt user to create a session key
}
const sessionClient = sessionData ? new SessionKey({ /* … */ }) : undefined;
return new Synapse({ client, sessionClient });
}

Balances & Storage Metrics

The dApp calculates and displays crucial balance and storage metrics to help users manage their storage costs effectively.

useBalances (src/hooks/use-balances.ts)

This React Query hook returns combined wallet and storage data:

filBalance: bigint # Native FIL
usdfcBalance: bigint # USDFC ERC-20 token
warmStorageBalance: bigint # Available funds in Synapse Pay contract
depositNeeded: bigint # USDFC shortfall (0 if sufficient)
availableToFreeUp: bigint # Excess beyond configured needs (safe to withdraw)
daysLeft: string # Days of storage at max configured capacity
daysLeftAtCurrentRate: string # Days at current usage rate
isSufficient: boolean # Rate + lockup + deposit all OK
isRateSufficient: boolean # Rate allowance set to unlimited
isLockupSufficient: boolean # Lockup allowance set to unlimited
totalConfiguredCapacity: number # GiB from user config
currentMonthlyRate: bigint # Wei/month at current usage
maxMonthlyRate: bigint # Wei/month if storage filled

fetchStorageMetrics (src/lib/storage-metrics.ts)

This is the core calculation engine used by `useBalances` and upload hooks. It calculates monthly rates, deposit shortfalls, and withdrawal safety based on on-chain pricing and user configuration.

Get FIL-B’s stories in your inbox

Join Medium for free to get updates from this writer.

Inputs: client, address, config { storageCapacity, persistencePeriod, minDaysThreshold }, fileSize?, newDatasets? { count, withCDN }

useStorageOverview (src/hooks/use-storage-overview.ts)

This hook combines useBalances and useDataSets into a single object for use in the dashboard.

Payments

The Synapse payment system relies on two allowances:

  • Rate Allowance: Maximum USDFC per epoch for ongoing storage payments.
  • Lockup Allowance: Total USDFC reserved upfront for persistence duration.

User preferences for storage capacity and persistence period are persisted to localStorage via Zustand in src/providers/storage-config/.

Upload System

The dApp supports multi-file, multi-copy uploads with three modes:

Press enter or click to view image in full size

Upload Flow (standard/CDN)

src/app/upload/hooks/use-upload.ts orchestrates the standard and CDN upload process:

  1. Init Synapse client: getSynapseClient() checks for a session key.
    2. Create contexts: synapse.storage.createContexts() creates/reuses datasets.
    3. Balance check: fetchStorageMetrics() determines if the balance is sufficient.
    4. Store-Pull-Commit: uploadToContexts() performs the actual upload.
    — Store: Upload files once to the primary provider.
    — Pull: Secondary providers pull from the primary.
    — Presign: ctx.presignForCommit() before pull.
    — Commit: Each provider confirms pieces on-chain.
    5. Results: The dApp displays results grouped by piece with provider details.

Filecoin Pin Mode

src/app/upload/hooks/use-pin-upload.ts handles the Filecoin Pin upload process:

1. Build CAR: buildCarFromFiles(files) creates a CAR file from the uploaded files.
2. Upload CAR: The CAR file is uploaded using the store-pull-commit flow.
3. IPNI verification: waitForIpniProviderResults(rootCid) verifies that the content is announced on IPNI.

Datasets & Files

The dApp provides functionalities for managing datasets and files stored on Filecoin.

Dataset Transformation

src/lib/datasets.ts contains functions for transforming and computing dataset information:

- transformDatasets(raw): Normalizes SDK datasets.
- computeUniquePieces(datasets): Deduplicates pieces across datasets.
- getDatasetsCostInfo(datasets, pricing): Calculates per-dataset monthly costs.

Download

src/hooks/use-download.ts provides the useDownloadPiece hook for downloading pieces. This hook validates the downloaded data against the expected CID using downloadAndValidate() and detects the MIME type using fileTypeFromBuffer() before triggering the browser download.

Delete

src/hooks/use-delete.tsprovides hooks for deleting pieces and datasets:

- useDeletePiece(dataSetId, pieceId): Deletes a piece from a dataset using the session key.
- useDeleteDataset(dataSetId): Terminates a dataset.

Getting Started

To get started with the Filecoin Onchain Cloud dApp, follow these steps:

git clone https://github.com/FIL-Builders/foc-upload-dapp
cd fs-upload-dapp
pnpm install
pnpm dev

Open http://localhost:3000 in your browser. You will need a web3 wallet with testnet tokens. You can use the built-in faucet or the following faucets:

- tFIL — Calibration Faucet
- tUSDFC— ChainSafe Faucet

Connect your blockchain wallet and experience the Filecoin Onchain Cloud.

Conclusion

The Filecoin Onchain Cloud dApp provides a comprehensive and user-friendly solution for managing decentralized storage on Filecoin. By leveraging the Synapse SDK and implementing features like session keys and automated payment handling, the dApp simplifies the process of storing and retrieving data on the Filecoin network. Developers can use this dApp as a starting point for building their own decentralized storage applications and contribute to the growth of the Filecoin ecosystem.

Wanna learn more? Head over the developer documentation and start building on Filecoin OnChain Cloud.

Thank you for reading! If you’re excited about building with Filecoin and decentralized storage, let’s stay connected 🦾

Twitter | Discord | Telegram | Slack | Contact Us

FIL-B
FIL-B

Written by FIL-B

FIL-B is the public goods developer experience (DX) team for the Filecoin ecosystem, helping builders successfully develop on-chain solutions.