What is Blockchain Storage?
Every story you save in eStory is permanently pinned to IPFS (InterPlanetary File System), a decentralized storage network. Your story metadata—title, content, author wallet, audio URL, and timestamps—becomes an immutable record linked to your wallet address. This creates sovereign ownership: you control the data, and no central authority can delete or censor it.Why Use Blockchain Storage?
Permanence
Stories are stored forever on IPFS nodes. Even if eStory shuts down, your data persists.
Censorship Resistance
No one can delete or alter your stories—not eStory, not governments, not hackers.
Proof of Authorship
Your wallet address cryptographically proves you authored the story at a specific time.
Data Portability
IPFS hashes let you retrieve your stories from any IPFS gateway—no lock-in.
How Stories Are Stored
Save Your Story
When you click Save Privately or Publish & Save, the following happens in parallel:
- Audio upload (if recorded): Original audio → Supabase Storage
- IPFS upload: Story metadata → Pinata IPFS pinning service
- Database save: Story record → Supabase PostgreSQL
- Vault encryption (optional): Encrypted copy → Local IndexedDB
IPFS Metadata Structure
Your story is encoded as JSON and uploaded to IPFS:Two timestamps:
date: User-selected memory date (for backdating)timestamp: Actual upload time (system clock)
Pinata Pinning
The metadata JSON is sent to Pinata (IPFS pinning service) via
/api/ipfs/upload. Pinata:- Uploads the file to IPFS network
- Returns a CID (Content Identifier) like
QmXyz... - Keeps the file pinned (prevents garbage collection)
CID is a cryptographic hash of the content—changing even one character creates a different CID.
Database Record
The story is saved to Supabase
stories table with:author_id: Your user ID (UUID)author_wallet: Your wallet address (Ethereum format)ipfs_hash: The IPFS CID from Pinatais_public: Visibility flag (true/false)created_at: System timestampstory_date: User-selected memory date
IPFS Technical Details
Content Identifier (CID)
Every IPFS file gets a unique CID based on its content hash. Example CID:- Deterministic: Same content → same CID
- Tamper-proof: Changing content changes CID
- Universal: Retrievable from any IPFS node
Pinning vs. Unpinning
| Concept | Explanation |
|---|---|
| Pinning | Tells IPFS nodes to keep the file cached permanently (prevents garbage collection) |
| Unpinning | Allows IPFS to delete the file if space is needed |
Data Availability
Who can access IPFS data?
Who can access IPFS data?
Public stories: Anyone with the CID can view the content via IPFS gateways.Private stories: The
is_public: false flag in metadata is informational only. IPFS itself is public—privacy relies on:- Not sharing the CID (keep it secret)
- Local Vault encryption (content encrypted before IPFS upload in future version)
Blockchain Verification (Future)
Current State: Off-Chain Storage
Currently, IPFS hashes are stored in Supabase (centralized database). Authorship is proven by:- Wallet signature during login
author_walletfield in database
Future: On-Chain Attestation
Roadmap (Phase 2): Stories will be anchored on Base L2 blockchain:
- IPFS CID stored in smart contract
- Author wallet cryptographically linked on-chain
- Timestamp immutably recorded in block
Smart Contract Integration
eStory uses Base Sepolia testnet (chain ID: 84532) for Web3 features:Deployed Contracts
| Contract | Purpose | Address |
|---|---|---|
| eStoryToken | ERC20 $STORY token | 0xf9eDD76B... |
| StoryNFT | ERC721 story books | 0x6D37ebc5... |
| PrivateVerifiedMetrics | CRE-attested insights | 0x158e08BC... |
How NFT Minting Works (Story Books)
How NFT Minting Works (Story Books)
You can mint a Story Book NFT from multiple journal entries:
- Compile stories into a book (via
/api/book/compile) - Upload book metadata to IPFS
- Call
StoryNFT.mintBook()with IPFS hash - Pay 0.001 ETH mint fee
- Receive ERC721 token (tradable, provable ownership)
/contracts/StoryNFT.solIPFS Upload API
Endpoint
Response
Rate Limits
Retrieving Your Stories from IPFS
Method 1: IPFS Gateway
Visit any public gateway with your CID:Method 2: IPFS Desktop Client
Install IPFS Desktop and fetch:Method 3: eStory Library
Your stories are indexed in the app’s Library page, with IPFS hashes stored in the database. Click any story to view its metadata including the IPFS link.Storage Cost Breakdown
| Component | Cost | Notes |
|---|---|---|
| IPFS pinning (Pinata) | Free (1 GB limit) | Paid plans: $20/mo for 100 GB |
| Supabase database | Free (500 MB limit) | Paid plans: $25/mo for 8 GB |
| Supabase audio storage | Free (1 GB limit) | Paid plans: $25/mo for 100 GB |
| Base L2 gas fees | ~$0.01 per tx | Only for future on-chain anchoring |
Data Redundancy & Backup
What if Pinata shuts down?
What if Pinata shuts down?
Your IPFS CID is stored in Supabase. You can:
- Download the story JSON from the database
- Re-pin it to a different IPFS service (e.g., Infura, Filebase)
- Or host your own IPFS node
What if Supabase data is lost?
What if Supabase data is lost?
IPFS acts as your backup. If you have the CIDs, you can:
- Query IPFS gateways to retrieve story metadata
- Reconstruct your library from IPFS data
- Re-import to a new database
Local Vault as third backup layer
Local Vault as third backup layer
Stories saved while Vault is unlocked are also encrypted in IndexedDB (browser storage). This provides:
- Offline access
- Client-side encryption (AES-256-GCM)
- Instant retrieval without network calls
Privacy Considerations
Comparison: IPFS vs. Traditional Storage
| Feature | IPFS (Decentralized) | AWS S3 (Centralized) |
|---|---|---|
| Permanence | Forever (if pinned) | Until you pay bills |
| Censorship | Resistant | Vulnerable |
| Access control | Public by default | Granular permissions |
| Cost | Pay for pinning | Pay for storage + bandwidth |
| Speed | Varies by node | Fast, consistent |
| Ownership | Cryptographic proof | AWS owns infrastructure |
Troubleshooting
”Failed to pin to IPFS”
Causes:- Pinata API key missing/invalid
- Rate limit exceeded
- Network timeout
PINATA_API_KEY and PINATA_API_SECRET in .env.
Story shows “IPFS hash: null”
Cause: IPFS upload failed but database save succeeded. Solution: This is a partial save. The story exists in Supabase but isn’t decentralized. Re-save the story to retry IPFS upload.Can’t access IPFS gateway
Cause: Gateway downtime or network blocking. Solution: Try alternative gateways:https://ipfs.io/ipfs/<CID>https://cloudflare-ipfs.com/ipfs/<CID>https://gateway.pinata.cloud/ipfs/<CID>
Next Steps
Local Vault
Add client-side encryption for true privacy before IPFS upload
Cognitive Insights
Extract AI insights from your blockchain-stored stories
Story Books (NFTs)
Mint ERC721 NFTs from your IPFS-backed stories