refactor(api): replace Arweave uploads with Supabase public bucket (phase 1)

Closed
AR
6mo ago
+767-376

Summary

Phase 1 of the Arweave→Supabase upload migration. Removes every Arweave write code path in api (Arweave wallet has been broken in production: every real upload returns "Transaction verification failed") and rewires each consumer to a new public Supabase bucket. The POST /api/upload wire contract stays byte-identical so the chat-side cutover (recoupable/chat#1718) needs no changes other than allowing the new image hostname in next.config.mjs.

Storage paths are flat opaque UUIDs at the bucket root — no scope encoding, no path semantics. Phase-2 access control will resolve through the parent resource that references the file (chat / account / artist).

Out of scope (deferred to phase 2): Bearer auth, signed URLs, private buckets, files-table changes, LLM-context URL rewriting, rate limiting.

Plan: PHASE_1_UPLOAD_MIGRATION_PLAN.md in the monorepo root.
Bucket-creation migration: recoupable/database#23 — must land before this PR.

What changes

Adds

  • lib/supabase/storage/getPublicUrlByKey.ts
  • lib/files/uploadDataToPublicBucket.ts (unified helper)
  • lib/files/uploadFileHandler.ts (POST /api/upload)
  • lib/files/mirrorUrlToPublicBucket.ts (replaces uploadLinkToArweave)
  • lib/networking/isSafeHttpUrl.ts (moved from lib/arweave/)
  • lib/image/uploadImageAndCreateMoment.ts (moved + Supabase swap)
  • 3 new constants in lib/const.ts: SUPABASE_PUBLIC_UPLOADS_BUCKET, MAX_UPLOAD_BYTES, SUPPORTED_UPLOAD_MIME

Rewires (Arweave → Supabase via uploadDataToPublicBucket)

  • /api/upload, /api/x402/image/generate
  • handleInstagramProfileScraperResults (apify webhook)
  • createImageMoment, generateAndStoreTxtFile, createKnowledgeBase, generateAndProcessImage, registerGenerateTxtFileTool

Removes

  • lib/arweave/upload*.ts (all upload helpers)
  • lib/arweave/client.ts (no consumers after upload helpers)
  • lib/arweave/isSafeHttpUrl.ts (moved)
  • arweave npm dep

Read-side helpers (getFetchableUrl, arweaveGatewayUrl, IPFS utilities) stay — still needed for legacy URLs in DB/messages.

Test plan

  • pnpm test — 2476/2476 passing (15 new tests covering the new helpers)
  • pnpm lint:check clean
  • pnpm format:check clean
  • After database PR #23 lands: smoke curl -F file=@x.png $PREVIEW/api/upload returns 200 with https://*.supabase.co/.../<uuid>.png
  • Verify the URL fetches with 200 + correct content-type + cache-control: max-age=31536000
  • Per-feature sanity: trigger apify Instagram webhook, image generation, knowledge-base save, txt-file tool — all return Supabase URLs
  • Chat preview (#1718): drag-drop a PNG; image renders end-to-end

Summary by CodeRabbit

  • New Features

    • Added a new file upload API endpoint with CORS support for uploading files to cloud storage.
  • Refactor

    • Migrated image storage from decentralized to cloud-based infrastructure for improved reliability and performance.
    • Updated image generation and knowledge base creation to use cloud storage instead of previous storage method.
    • Updated Instagram profile data processing to use cloud storage infrastructure.