DEV Community

Cover image for MemoryLane: Building A Dynamic Time Capsule App with Pinata FILE API
DrPrime01
DrPrime01

Posted on

MemoryLane: Building A Dynamic Time Capsule App with Pinata FILE API

This is a submission for the The Pinata Challenge

What I Built

I built MemoryLane, a digital time capsule application that allows users to preserve moments and thoughts as files and rediscover them in the future. The project combines the nostalgia of traditional time capsules with modern cloud storage technology, leveraging Pinata's File API for secure and efficient file management.

Key features of MemoryLane include:

  • Digital preservation of memories
  • Future revelations based on user-set dates
  • Flexible time-frames for capsule opening
  • Multi-media experiences (supporting various file types)
  • Personal and collaborative options
  • Security and privacy
  • Cloud-based reliability

The application was built using:

  • NextJS (TypeScript variant)
  • Pinata SDK for file uploads and management
  • React-dropzone for handling file inputs
  • Axios for API calls
  • Date-fns for date formatting

Technical implementation highlights:

  1. Project setup with NextJS and necessary dependencies
  2. Integration with Pinata using environment variables for API keys
  3. Custom components for file upload and time capsule display
  4. Server-side API route for handling file uploads to Pinata
  5. Client-side state management for time capsules using React hooks
  6. Local storage integration for persisting time capsules between sessions
  7. Deployment to Vercel for hosting the application

The project demonstrates the use of Pinata's features including:

  • File uploads using the Pinata SDK
  • Creation of signed URLs for secure file access
  • Integration with NextJS API routes for server-side file handling

This project showcases how Pinata can be effectively used in a Web2 application, highlighting its versatility beyond Web3 and dApp development.

Demo

Link: MemoryLane

Image description

Image description

My Code

MemoryLane GitHub

More Details

In the MemoryLane project, Pinata's features were integral to the core functionality of storing and retrieving time capsule files. Here are detailed examples of how Pinata was used:

  1. Pinata SDK Integration: The project uses Pinata SDK for seamless interaction with Pinata's services. This is set up in the utils/config.ts file:
   import { PinataSDK } from "pinata"

   export const pinata = new PinataSDK({
     pinataJwt: `${process.env.PINATA_JWT}`,
     pinataGateway: `${process.env.NEXT_PUBLIC_PINATA_GATEWAY_URL}`
   })
Enter fullscreen mode Exit fullscreen mode

This configuration allows the application to use Pinata's services throughout the server-side code.

  1. File Upload to Pinata: In the api/files/route.ts file, we handle file uploads using Pinata's SDK:
   import { NextResponse, NextRequest } from "next/server";
import { pinata } from "@/utils/config";

export async function POST(req: NextRequest) {
  try {
    const data = await req.formData();
    const file: File | null = data.get("file") as unknown as File;
    const uploadData = await pinata.upload.file(file);
    const url = await pinata.gateways.createSignedURL({
      cid: uploadData.cid,
      expires: 360000,
    });
    return NextResponse.json({ url }, { status: 200 });
  } catch (e) {
    console.error(e);
    return NextResponse.json(
      { error: "Internal Server Error" },
      { status: 500 }
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

This code snippet demonstrates how we use Pinata to upload files directly from the user's input.

  1. Creating Signed URLs: After uploading a file, we generate a signed URL for secure access:
   const url = await pinata.gateways.createSignedURL({
     cid: uploadData.cid,
     expires: 360000,
   });
Enter fullscreen mode Exit fullscreen mode

This signed URL ensures that only authorized users can access the uploaded files, enhancing the security of our time capsules.

  1. Frontend Integration: On the frontend, we use these signed URLs to display images securely:
   import Image from "next/image";
import { format } from "date-fns";

import InfoIcon from "@/assets/icons/info-icon";
import LockIcon from "@/assets/icons/lock-icon";
import { TimeCapsuleStateType } from "@/types";

export default function TimeCapsule({
  url,
  openDate,
  created_at,
}: TimeCapsuleStateType) {
  return (
    <div className="flex flex-col gap-y-2 max-w-[240px]">
      <div className="relative">
        <Image
          src={url}
          width={240}
          height={240}
          alt="time capsule"
          className="object-cover aspect-square"
        />
        {new Date() < new Date(openDate) && (
          <div className="absolute bg-black/85 inset-0 flex items-center justify-center">
            <LockIcon />
          </div>
        )}
      </div>
      <p className="text-sm font-medium text-gray-700">
        To be opened on {format(openDate, "dd/MM/yyyy")}
      </p>
      <div className="bg-gray-200 flex space-x-1.5 p-2 rounded-xl">
        <InfoIcon />
        <p className="text-xs text-gray-500">
          This time capsule was created on {format(created_at, "dd/MM/yyyy")}
        </p>
      </div>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

The url here is the signed URL returned from Pinata, allowing us to display the time capsule images without exposing the raw file locations.

  1. Configuring for Pinata's Gateway: To ensure NextJS can properly handle images from Pinata's gateway, we configured the next.config.mjs file:
   const nextConfig = {
     images: {
       remotePatterns: [
         {
           protocol: "https",
           hostname: "your-gateway-url.mypinata.cloud",
         },
       ],
     },
   };
Enter fullscreen mode Exit fullscreen mode

This configuration allows NextJS to optimize and serve images from Pinata's gateway efficiently.

By leveraging these features of Pinata, MemoryLane achieves:

  • Secure file storage: Files are stored on Pinata's decentralized network, ensuring durability and availability.
  • Controlled access: Signed URLs provide a secure way to access files, perfect for the time-release nature of digital time capsules.
  • Efficient retrieval: Pinata's gateway ensures fast access to files when it's time to "open" a time capsule.

See here for the full article, explaining the implementation from start to finish.

Cover image by ChatGPT

Top comments (0)