Skip to content

fix token provider reference#896

Open
techeng322 wants to merge 5 commits intomainfrom
techengme/myc-3542-moment-page-using-new-supabase-table
Open

fix token provider reference#896
techeng322 wants to merge 5 commits intomainfrom
techengme/myc-3542-moment-page-using-new-supabase-table

Conversation

@techeng322
Copy link
Copy Markdown
Collaborator

@techeng322 techeng322 commented Nov 27, 2025

Summary by CodeRabbit

  • New Features

    • API now returns richer Moment payload: uri, owner, saleConfig, expanded metadata (name, image, description, content, animation_url) and momentAdmins.
    • New MomentProvider exposes consolidated moment + derived on‑chain/database info to UI.
  • Refactor

    • App migrated from token‑centric to moment‑centric data model, hooks and providers.
    • Public query param renamed tokenContract → collectionAddress with stricter validation (400 on invalid input).
  • Bug Fixes

    • Safer handling of optional content fields to avoid runtime errors.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link
Copy Markdown

vercel bot commented Nov 27, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
in-process Ready Ready Preview Nov 28, 2025 1:59am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 27, 2025

Walkthrough

Replaces token-centric APIs/providers/hooks with a Moment-based model: introduces Moment types and MomentProvider, replaces getTokenInfo with getMomentOnChainInfo/getMomentAdvancedInfo, updates API routes, libs, hooks, components, and DB selectors to accept/consume a single Moment ({ collectionAddress, tokenId, chainId }).

Changes

Cohort / File(s) Summary
API: moment endpoints
app/api/moment/route.ts, app/api/moment/update-uri/route.ts, app/api/moment/comments/route.ts
Query/POST shapes now use a Moment (collectionAddress, tokenId, chainId); GET builds Moment, calls getMomentAdvancedInfo, validates with getMomentSchema, and returns { uri, owner, saleConfig, momentAdmins, metadata }. update-uri and comments adjusted to accept Moment.
On‑chain helpers
lib/viem/getTokenInfo.ts (→ getMomentOnChainInfo), lib/viem/getCollectCall.ts, lib/viem/...
Renamed to accept a single Moment; on‑chain calls use collectionAddress and moment.chainId; enum/type refs migrated from MintType → MomentType.
Moment aggregation & logic
lib/moment/getMomentAdvancedInfo.ts, lib/moment/indexMoment.ts, lib/moment/collectMoment.ts, lib/moment/fetchComments.ts, lib/moment/momentComments.ts, lib/moment/validateBalanceAndAllowance.ts
New getMomentAdvancedInfo(moment) merges DB and on‑chain sale sources; other helpers updated to input/output Moment-shaped data and use collectionAddress/chainId.
Supabase selectors & converters
lib/supabase/in_process_moments/selectMoment.ts, lib/supabase/in_process_sales/selectSale.ts, lib/supabase/in_process_admins/selectAdmins.ts, lib/sales/convertDatabaseSaleToApi.ts, lib/sales/convertOnChainSaleToApi.ts
Added/updated DB accessors that accept Moment; added converters mapping DB/on‑chain sale shapes to MomentApiSaleConfig.
API clients
lib/moment/getMomentApi.ts, lib/moment/collectMomentApi.ts, lib/moment/fetchComments.ts
Client functions now accept a single Moment param, adjust URLSearchParams/body accordingly, and add explicit error/response handling.
Providers
providers/MomentProvider.tsx, (removed) providers/TokenProvider.tsx
Introduced MomentProvider + useMomentProvider() exposing raw moment and derived data; removed TokenProvider and useTokenProvider.
Hooks & consumers
hooks/*, components/* (many files)
e.g. hooks/useMoment.ts, hooks/useComments.ts, hooks/useMomentCollect.ts, hooks/useBalanceOf.ts, hooks/useAirdrop.ts, hooks/useSaleConfig.ts, hooks/useUpdateMomentURI.ts, hooks/useMetadata.ts, components/TokenPage/*, components/TokenManagePage/*, components/Renderers/ContentRenderer.tsx, components/ArtSlider/*
Replaced useTokenProvider()useMomentProvider() across numerous files; hooks refactored to accept/consume Moment; types updated to MomentMetadata.
Types & schemas
types/moment.ts, types/sale.ts, (removed) types/token.ts, types/zora.ts, types/dune.ts, types/fetch-collections.ts, types/jam.ts
lib/schema/getMomentSchema.ts, lib/schema/collectSchema.ts, lib/schema/commentsSchema.ts
Added Moment-centric types (Moment, MomentMetadata, MomentType, MomentAdvancedInfo, MomentApiSaleConfig); added sale types; renamed contractAddresscollectionAddress, added chainId defaults; removed legacy token/zora/dune/fetch-collections/jam types.
Misc — safety, removals, small updates
app/api/og/*, removed lib/viem/getNextTokenIds.ts, removed hooks/useToken.ts, many import/type swaps
Added optional chaining for metadata.content in OG routes; removed obsolete modules and token-centric hooks/types; replaced MintType references with MomentType.

Sequence Diagram(s)

mermaid
sequenceDiagram
autonumber
actor Client
participant API as /api/moment
participant DB as Supabase
participant OnChain as On‑Chain Service
participant Meta as Metadata Service
participant Admins as In‑process Admins

Client->>API: GET /api/moment?collectionAddress&tokenId&chainId
API->>DB: selectMoment(moment)
alt moment exists in DB
    DB-->>API: momentData (id, uri, collection.default_admin)
    API->>DB: selectSale(momentData.id)
    alt sale exists in DB
        DB-->>API: databaseSale
        API->>API: convertDatabaseSaleToApi(databaseSale)
    else no DB sale
        API->>OnChain: getMomentOnChainInfo(moment)
        OnChain-->>API: onChainSale, owner, tokenUri
        API->>API: convertOnChainSaleToApi(onChainSale)
    end
else moment not in DB
    API->>OnChain: getMomentOnChainInfo(moment)
    OnChain-->>API: onChainSale, owner, tokenUri
    API->>API: convertOnChainSaleToApi(onChainSale)
end
API->>Meta: fetchTokenMetadata(uri or tokenUri)
API->>Admins: selectAdmins(moment)
Meta-->>API: metadata
Admins-->>API: admins
API-->>Client: { uri, owner, saleConfig, momentAdmins, metadata }

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Files/areas needing careful review:
    • app/api/moment/route.ts and lib/moment/getMomentAdvancedInfo.ts — DB vs on‑chain selection, sale conversion correctness, error paths.
    • lib/viem/getMomentOnChainInfo.ts — on‑chain call signatures, ABI args, chain client usage.
    • providers/MomentProvider.tsx and widespread useTokenProvider → useMomentProvider replacements — ensure context shape and consumers align.
    • Large type removals (types/token.ts, types/zora.ts, etc.) — check for lingering imports and type mismatches.
    • Client ↔ API serialization of Moment (getMomentApi / fetchComments) and schema defaults for chainId.

Possibly related PRs

  • integrate get moment info api #871 — Similar migration from token-centric to moment-centric APIs/providers; likely overlaps in getMoment/getMomentAdvancedInfo, provider and hook replacements.

Poem

🐰 I hopped through types and swapped a name,

collectionAddress leading the game,
Providers changed, the moments now sing,
I nibble new types and cheer for this spring,
Code compiles — I munch on a carrot of fame 🥕

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'fix token provider reference' is too vague and does not accurately describe the extensive scope of changes in this PR. Use a more specific title that reflects the major refactoring, such as 'Refactor token provider to moment provider and update data models' or 'Migrate TokenProvider to MomentProvider with updated schemas'.
Docstring Coverage ⚠️ Warning Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch techengme/myc-3542-moment-page-using-new-supabase-table

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
components/CreatedMoment/CreatedMomentAirdrop.tsx (1)

7-22: Fix MomentProvider props: pass a moment object instead of token/chainId

CreatedMomentAirdrop now wraps MomentAirdrop with MomentProvider, but it still passes token and chainId props:

<MomentProvider
  token={{ tokenContractAddress: createdContract as Address, tokenId: createdTokenId }}
  chainId={CHAIN_ID}
>

The MomentProvider implementation expects a moment prop (e.g., { collectionAddress, tokenId, chainId }), so this will fail type‑checking and the context won’t receive the intended data.

You likely want to construct a Moment object here:

-    <MomentProvider
-      token={{ tokenContractAddress: createdContract as Address, tokenId: createdTokenId }}
-      chainId={CHAIN_ID}
-    >
+    <MomentProvider
+      moment={{
+        collectionAddress: createdContract as Address,
+        tokenId: createdTokenId,
+        chainId: CHAIN_ID,
+      }}
+    >
       <MomentAirdrop />
-    </MomentProvider>
+    </MomentProvider>

Adjust the property names if your Moment type uses a different field name for the address, but the key point is to pass a single moment object matching MomentProvider’s expected props.

lib/moment/getMomentApi.ts (1)

1-10: Bug: JSON.stringify(moment) passed directly into URLSearchParams will not build the intended query

URLSearchParams expects a query string like "a=1&b=2" or a key/value object. Passing a raw JSON string:

const params = new URLSearchParams(JSON.stringify(moment));

produces a single, essentially meaningless query key/value (e.g. {"collectionAddress":"...","tokenId":"1","chainId":8453}) rather than proper parameters. The /api/moment route will almost certainly not receive the fields it expects.

You likely want either:

  • Top‑level query params for each Moment field, or
  • A single moment param containing the JSON string.

For top‑level params (closest to traditional usage):

-import { Moment } from "@/types/moment";
-
-export const getMomentApi = async (moment: Moment) => {
-  const params = new URLSearchParams(JSON.stringify(moment));
+import { Moment } from "@/types/moment";
+
+export const getMomentApi = async (moment: Moment) => {
+  const params = new URLSearchParams({
+    collectionAddress: moment.collectionAddress,
+    tokenId: moment.tokenId,
+    chainId: String(moment.chainId),
+  });
   const res = await fetch(`/api/moment?${params.toString()}`);

If the API route instead expects a single moment param, adjust to:

const params = new URLSearchParams({
  moment: JSON.stringify(moment),
});

Either way, avoid passing JSON.stringify(moment) directly to URLSearchParams as it currently breaks the request.

hooks/useMomentCollect.ts (1)

41-45: Add null check for moment before accessing its properties.

The function checks saleConfig and artistWallet but not moment. If moment is undefined, accessing moment.collectionAddress on line 53 will throw.

   const collectWithComment = async () => {
     try {
       if (!saleConfig) return;
       if (!artistWallet) return;
+      if (!moment) return;
       setIsLoading(true);
app/api/moment/route.ts (1)

74-86: Add validation for momentdata.owner before calling getAddress.

If momentdata.owner is empty or invalid, getAddress() will throw, resulting in a generic 500 error. Consider adding explicit validation.

+    if (!momentdata.owner) {
+      return NextResponse.json({ error: "Owner not found" }, { status: 404 });
+    }
+
     return NextResponse.json({
       uri: momentdata.tokenUri,
       owner: getAddress(momentdata.owner),
🧹 Nitpick comments (15)
lib/schema/getMomentSchema.ts (1)

3-15: Consider normalizing chainId type across schemas

Here chainId is modeled as a string (with default(CHAIN_ID.toString())), while collectSchema uses a numeric chainId. If both represent the same concept, it may be worth normalizing to a single type (e.g., always a number in internal code and only treating it as a string at the HTTP/query boundary) to avoid repeated conversions and subtle mismatches.

hooks/useComments.ts (1)

6-27: useMomentProvider integration is fine; consider future naming alignment

Swapping to useMomentProvider while still consuming token.tokenContractAddress, tokenId, and chainId keeps the existing query behavior intact, assuming the Moment context continues to expose a token object with that shape.

Longer term, as the rest of the codebase moves toward collectionAddress/moment‑centric naming, it may be worth aligning the comments fetch payload and query key parameters with that terminology to reduce confusion between “token” vs “moment” shapes.

hooks/useShareMoment.ts (1)

3-13: Share hook’s switch to useMomentProvider preserves behavior

Using useMomentProvider to access token keeps the share URL logic unchanged and should work as before if the context still exposes tokenContractAddress/tokenId. If you eventually phase out the token-centric view in favor of a pure moment shape, this is a good candidate to update to read from moment.collectionAddress (or equivalent) at the same time.

components/TokenPage/Token.tsx (1)

3-16: MomentProvider integration preserves Token layout behavior

Reading metadata and isOwner from useMomentProvider slots into the existing render logic (metadata gate and owner-gated airdrop) without changing semantics. You may eventually want to align the component name with the “Moment” terminology, but that’s not required for this PR.

types/moment.ts (1)

5-8: Align moment-related type naming and tighten typings

The updated Moment interface with collectionAddress and chainId looks good, but:

  • CommentsQueryParams.contractAddress now diverges in naming from Moment.collectionAddress, which can be confusing when wiring API/query layers.
  • GetInProcessMomentsRpcResponse.moments: any[] and SaleConfig.type: string are loosely typed and go against the “strict TypeScript, zero any” guideline.

Consider (when feasible) renaming contractAddress to collectionAddress (or documenting the distinction) and replacing any[]/plain string with concrete types (e.g., Moment[] or a dedicated DTO type and a string union for SaleConfig.type).

Also applies to: 15-20, 45-60

hooks/useBalanceOf.ts (1)

2-26: Verify token shape from useMomentProvider matches balanceOf expectations

useBalanceOf now pulls { token } from useMomentProvider but still calls readContract with token.tokenContractAddress and token.tokenId. Given the broader shift toward a Moment shape with collectionAddress/chainId, this is a potential mismatch:

  • If token is now a Moment, this should likely use token.collectionAddress (and ensure tokenId is still the correct field).
  • If token intentionally remains a separate “token” object with tokenContractAddress, the naming and typing around MomentProvider vs token may be confusing.

Please confirm the actual context type and adjust either the field names or the typings to keep this consistent with the new Moment model.

lib/viem/getTokenInfo.ts (1)

12-64: Moment-based getMomentOnChainInfo looks correct; consider tightening client typing

The refactor to getMomentOnChainInfo(moment: Moment) cleanly switches all internal calls to collectionAddress, tokenId, and chainId and preserves the returned shape { saleConfig, tokenUri, owner }, so existing consumers should continue to work as long as they pass a numeric chainId.

One improvement to align with your strict typing guidelines: avoid publicClient: any and instead type it using the return type of getPublicClient:

const publicClient = getPublicClient(chainId);
// or
const publicClient: ReturnType<typeof getPublicClient> = getPublicClient(chainId);

This keeps the API change focused while eliminating an explicit any.

providers/MomentProvider.tsx (1)

1-34: MomentProvider / useMomentProvider are well-structured; ESLint disable appears stale

The new MomentProvider and useMomentProvider correctly wrap useMoment(moment) and expose both the raw moment and derived data via context, with a good safety check in the hook.

The // eslint-disable-next-line @typescript-eslint/no-explicit-any above createContext no longer seems necessary, since the generic type doesn’t use any. You can safely remove it to keep the lint rule effective for future edits in this file.

hooks/useUpdateMomentURI.ts (1)

2-88: Hook correctly migrated to MomentProvider; consider moving the context guard earlier

The hook now consistently uses useMomentProvider and getMomentOnChainInfo(moment), and passes moment.collectionAddress / moment.tokenId through to callUpdateMomentURI and migrateMuxToArweaveApi, which aligns with the new moment-centric model.

One minor robustness tweak: you currently call

const tokenInfo = await getMomentOnChainInfo(moment);

before checking:

if (!moment?.collectionAddress || !moment?.tokenId) {
  throw new Error("Missing token context");
}

If moment were ever missing or incomplete, the earlier on-chain call would throw with a less clear error. Consider moving the “Missing token context” check above the getMomentOnChainInfo call so the failure mode is deterministic and explicit.

Functionally the change looks good given a valid Moment context.

hooks/useMoment.ts (1)

49-49: Rename fetchTokenInfo to align with the new naming convention.

The hook and API have been renamed to use "Moment" terminology, but this returned property still uses "TokenInfo".

-    fetchTokenInfo: query.refetch,
+    fetchMoment: query.refetch,
hooks/useMomentCollect.ts (3)

14-14: Replace any with a proper type for parameters.

The coding guidelines require strict TypeScript with zero any. Consider typing this parameter properly.

-const mintOnSmartWallet = async (parameters: any) => {
+interface MintParameters {
+  address: Address;
+  abi: typeof zoraCreator1155ImplABI;
+  functionName: string;
+  args: unknown[];
+}
+
+const mintOnSmartWallet = async (parameters: MintParameters) => {

72-76: Avoid as any cast; type the comment object properly.

Per coding guidelines, avoid any types. The addComment call should accept a properly typed object.

       addComment({
         sender: artistWallet as Address,
         comment,
         timestamp: new Date().getTime(),
-      } as any);
+      });

If the type doesn't match, update the addComment function signature or create a proper type for new comments.


14-29: Consider extracting mintOnSmartWallet to a lib file.

Per coding guidelines, hooks should focus on state management, and business logic should go in lib files. Additionally, this file exceeds the 100-line limit. Extracting this utility would improve separation of concerns and reduce file size.

Move to lib/smartwallet/mintOnSmartWallet.ts:

import { Address } from "viem";
import { zoraCreator1155ImplABI } from "@zoralabs/protocol-deployments";

interface MintParameters {
  address: Address;
  abi: typeof zoraCreator1155ImplABI;
  functionName: string;
  args: unknown[];
}

export const mintOnSmartWallet = async (parameters: MintParameters) => {
  const response = await fetch(`/api/smartwallet/sendUserOperation`, {
    method: "POST",
    headers: {
      "content-type": "application/json",
      accept: "application/json",
    },
    body: JSON.stringify({ parameters }),
  });

  const data = await response.json();
  return data.transactionHash;
};
app/api/moment/route.ts (2)

3-3: Import path doesn't match the exported function name.

The import references @/lib/viem/getTokenInfo but imports getMomentOnChainInfo. Consider renaming the file to match the function name for clarity.

Either rename the file:

  • @/lib/viem/getTokenInfo.ts@/lib/viem/getMomentOnChainInfo.ts

Or update the import if the file has been renamed:

-import getMomentOnChainInfo from "@/lib/viem/getTokenInfo";
+import getMomentOnChainInfo from "@/lib/viem/getMomentOnChainInfo";

66-72: Replace any with a proper type for saleConfig.

Per coding guidelines, avoid any types. Define an interface for the sale configuration response.

+interface SaleConfigResponse {
+  pricePerToken: string;
+  saleStart: number;
+  saleEnd: number;
+  maxTokensPerAddress: number;
+  [key: string]: unknown; // for spread properties
+}

-    const saleConfig: any = {
+    const saleConfig: SaleConfigResponse = {
       ...momentdata.saleConfig,
       pricePerToken: pricePerToken.toString(),
       saleStart: Number(saleStart),
       saleEnd: Number(saleEnd),
       maxTokensPerAddress: Number(maxTokensPerAddress),
     };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7f3bfe6 and bdc481a.

📒 Files selected for processing (37)
  • app/api/moment/route.ts (3 hunks)
  • components/CollectionManagePage/TokenOverview.tsx (1 hunks)
  • components/CreatedMoment/CreatedMomentAirdrop.tsx (2 hunks)
  • components/TokenManagePage/AirdropButton.tsx (1 hunks)
  • components/TokenManagePage/AnimationUpload.tsx (1 hunks)
  • components/TokenManagePage/Media.tsx (2 hunks)
  • components/TokenManagePage/OwnerWarning.tsx (1 hunks)
  • components/TokenManagePage/Sale.tsx (1 hunks)
  • components/TokenManagePage/SaveMediaButton.tsx (1 hunks)
  • components/TokenManagePage/TokenManagePage.tsx (3 hunks)
  • components/TokenPage/BackToTimeline.tsx (1 hunks)
  • components/TokenPage/CollectModal.tsx (2 hunks)
  • components/TokenPage/CommentSection.tsx (2 hunks)
  • components/TokenPage/MetaAndComments.tsx (2 hunks)
  • components/TokenPage/Token.tsx (2 hunks)
  • components/TokenPage/TokenPage.tsx (2 hunks)
  • hooks/useAirdrop.ts (1 hunks)
  • hooks/useBalanceOf.ts (1 hunks)
  • hooks/useComments.ts (1 hunks)
  • hooks/useDownload.ts (1 hunks)
  • hooks/useMoment.ts (2 hunks)
  • hooks/useMomentCollect.ts (4 hunks)
  • hooks/useSaleConfig.ts (2 hunks)
  • hooks/useShareMoment.ts (1 hunks)
  • hooks/useToken.ts (0 hunks)
  • hooks/useUpdateMomentURI.ts (4 hunks)
  • lib/moment/collectMoment.ts (2 hunks)
  • lib/moment/collectMomentApi.ts (1 hunks)
  • lib/moment/getMomentApi.ts (1 hunks)
  • lib/moment/indexMoment.ts (1 hunks)
  • lib/mux/migrateMuxToArweave.ts (2 hunks)
  • lib/schema/collectSchema.ts (1 hunks)
  • lib/schema/getMomentSchema.ts (1 hunks)
  • lib/viem/getTokenInfo.ts (3 hunks)
  • providers/MomentProvider.tsx (1 hunks)
  • providers/TokenProvider.tsx (0 hunks)
  • types/moment.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • hooks/useToken.ts
  • providers/TokenProvider.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Minimize code to absolute minimum needed - avoid unnecessary abstractions, intermediate steps, or redundant patterns
Write self-documenting code through precise naming (verbs for functions, nouns for variables), single-responsibility components, obvious data flow, and add short comments only when necessary
Apply Single Responsibility Principle (SRP): each function/component should have ONE clear responsibility - extract functions into separate files when they handle distinct concerns - hooks focus on state management, business logic goes in lib files - each function should be in its own file when it has a distinct purpose
Use strict TypeScript types with zero 'any' - prioritize type-exact definitions
Implement built-in security for authentication and data handling - follow secure coding practices throughout the application
Follow Next.js optimization guides for performance - implement proper caching, code splitting, and rendering strategies
Keep all files under 100 lines of code to maintain readability and follow single responsibility principle - split hooks/components when they grow too large or handle multiple concerns
Before coding, make a plan inside a tag: identify core requirement, consider 3 implementation approaches, choose simplest that meets needs, verify if code can be split into smaller functions, check for unnecessary abstractions, and ensure clarity for junior developers

Files:

  • components/CreatedMoment/CreatedMomentAirdrop.tsx
  • components/TokenManagePage/Sale.tsx
  • components/TokenPage/MetaAndComments.tsx
  • lib/moment/collectMomentApi.ts
  • types/moment.ts
  • components/TokenManagePage/SaveMediaButton.tsx
  • hooks/useShareMoment.ts
  • components/TokenManagePage/AnimationUpload.tsx
  • components/TokenManagePage/Media.tsx
  • hooks/useDownload.ts
  • lib/moment/indexMoment.ts
  • components/TokenPage/CommentSection.tsx
  • components/TokenManagePage/OwnerWarning.tsx
  • hooks/useAirdrop.ts
  • hooks/useUpdateMomentURI.ts
  • hooks/useComments.ts
  • components/TokenManagePage/AirdropButton.tsx
  • components/TokenPage/BackToTimeline.tsx
  • lib/viem/getTokenInfo.ts
  • lib/moment/collectMoment.ts
  • providers/MomentProvider.tsx
  • components/TokenPage/CollectModal.tsx
  • lib/schema/collectSchema.ts
  • components/TokenManagePage/TokenManagePage.tsx
  • lib/mux/migrateMuxToArweave.ts
  • components/TokenPage/Token.tsx
  • lib/moment/getMomentApi.ts
  • lib/schema/getMomentSchema.ts
  • components/CollectionManagePage/TokenOverview.tsx
  • hooks/useBalanceOf.ts
  • hooks/useMomentCollect.ts
  • hooks/useSaleConfig.ts
  • components/TokenPage/TokenPage.tsx
  • app/api/moment/route.ts
  • hooks/useMoment.ts
lib/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Library files should contain pure business logic, data transformation, validation, and API calls - never include React state management or UI concerns

Files:

  • lib/moment/collectMomentApi.ts
  • lib/moment/indexMoment.ts
  • lib/viem/getTokenInfo.ts
  • lib/moment/collectMoment.ts
  • lib/schema/collectSchema.ts
  • lib/mux/migrateMuxToArweave.ts
  • lib/moment/getMomentApi.ts
  • lib/schema/getMomentSchema.ts
hooks/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Hooks should focus exclusively on state management and data fetching - extract business logic, validation, and data transformation into separate lib files

Files:

  • hooks/useShareMoment.ts
  • hooks/useDownload.ts
  • hooks/useAirdrop.ts
  • hooks/useUpdateMomentURI.ts
  • hooks/useComments.ts
  • hooks/useBalanceOf.ts
  • hooks/useMomentCollect.ts
  • hooks/useSaleConfig.ts
  • hooks/useMoment.ts
🧬 Code graph analysis (27)
components/CreatedMoment/CreatedMomentAirdrop.tsx (2)
providers/MomentProvider.tsx (1)
  • MomentProvider (13-26)
lib/consts.ts (1)
  • CHAIN_ID (20-20)
components/TokenManagePage/Sale.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenPage/MetaAndComments.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenManagePage/SaveMediaButton.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
hooks/useShareMoment.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenManagePage/AnimationUpload.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenManagePage/Media.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
hooks/useDownload.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenManagePage/OwnerWarning.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
hooks/useAirdrop.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
hooks/useUpdateMomentURI.ts (2)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
lib/mux/migrateMuxToArweaveApi.ts (1)
  • migrateMuxToArweaveApi (18-43)
hooks/useComments.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenManagePage/AirdropButton.tsx (2)
providers/AirdropProvider.tsx (1)
  • useAirdropProvider (21-27)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenPage/BackToTimeline.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
lib/moment/collectMoment.ts (1)
lib/moment/validateBalanceAndAllowance.ts (1)
  • validateBalanceAndAllowance (15-40)
providers/MomentProvider.tsx (1)
types/moment.ts (1)
  • Moment (4-8)
components/TokenPage/CollectModal.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
lib/schema/collectSchema.ts (2)
lib/schema/commentsSchema.ts (1)
  • momentSchema (4-7)
lib/consts.ts (1)
  • CHAIN_ID (20-20)
components/TokenManagePage/TokenManagePage.tsx (1)
providers/MomentProvider.tsx (1)
  • MomentProvider (13-26)
lib/mux/migrateMuxToArweave.ts (1)
lib/consts.ts (1)
  • CHAIN_ID (20-20)
components/TokenPage/Token.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
lib/moment/getMomentApi.ts (1)
types/moment.ts (1)
  • Moment (4-8)
lib/schema/getMomentSchema.ts (1)
lib/consts.ts (1)
  • CHAIN_ID (20-20)
components/CollectionManagePage/TokenOverview.tsx (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
hooks/useBalanceOf.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
hooks/useSaleConfig.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
components/TokenPage/TokenPage.tsx (3)
providers/MomentProvider.tsx (1)
  • MomentProvider (13-26)
providers/MomentCommentsProvider.tsx (1)
  • MomentCommentsProvider (14-31)
providers/MomentCollectProvider.tsx (1)
  • MomentCollectProvider (26-26)
🔇 Additional comments (24)
lib/schema/collectSchema.ts (1)

3-9: Schema updates for collectionAddress/chainId look correct

Importing CHAIN_ID, renaming to collectionAddress, and adding chainId: z.number().optional().default(CHAIN_ID) are consistent and should give you a reliably populated numeric chainId on parsed moments. Just be aware that with the default in place, inferred types will now treat chainId as always defined after parsing, so any call sites that still assume it can be undefined may need tightening.

hooks/useDownload.ts (1)

2-7: Provider swap to useMomentProvider looks safe

Using useMomentProvider to get metadata preserves the existing download logic and keeps the hook focused on state + side effects. As long as MomentProvider exposes metadata with the same data/content shape, this should be a drop‑in replacement.

hooks/useAirdrop.ts (1)

11-21: Airdrop hook now sourcing token from MomentProvider looks correct

Pulling token from useMomentProvider and deriving momentContract/tokenId keeps the airdrop payload the same, so executeAirdrop should behave identically to the TokenProvider version provided the context still exposes those fields.

components/TokenManagePage/Sale.tsx (1)

4-10: Sale component’s migration to useMomentProvider is straightforward

Reading saleConfig from useMomentProvider while keeping useSaleConfig for local state/effects maintains the existing control flow and safeguards. Assuming saleConfig in the Moment context matches the prior TokenProvider shape, this should be a non‑breaking swap.

components/CollectionManagePage/TokenOverview.tsx (1)

6-10: Provider swap to useMomentProvider is consistent

Using metadata and isLoading from useMomentProvider mirrors the prior TokenProvider usage and integrates cleanly with existing rendering and skeleton states. No issues from this change alone.

components/TokenPage/BackToTimeline.tsx (1)

3-12: Owner sourced from useMomentProvider correctly

owner from useMomentProvider is used in exactly the same way as before (profile lookup, lowercased route, null-guarded). The provider swap is safe and preserves behavior.

components/TokenPage/MetaAndComments.tsx (1)

1-20: Sale/metadata now sourced from MomentProvider without behavior change

Switching to useMomentProvider for saleConfig, metadata, isLoading, and isSetSale keeps the existing price and comments logic intact, with the same guards around metadata and sale state.

components/TokenPage/CollectModal.tsx (1)

3-20: Collect modal now correctly reads from MomentProvider

Using useMomentProvider for saleConfig, isLoading, isSetSale, and metadata maintains the previous control flow (early return when sale isn’t configured, same disabled state and price display). The swap looks safe.

lib/moment/collectMomentApi.ts (1)

4-20: Sending full Moment object in collect payload is consistent with new model

Passing the Moment object directly in the POST body (moment, amount, comment) matches the updated Moment-centric typing and keeps the call site simple. As long as /api/moment/collect expects this shape, this change is correct and improves cohesion around the Moment type.

components/TokenPage/CommentSection.tsx (1)

1-1: MomentProvider swap for isSetSale looks correct

Using useMomentProvider here to source isSetSale aligns with the new Moment-based context and keeps the rendering logic unchanged. No issues from a correctness or clarity standpoint.

Also applies to: 10-10

components/TokenManagePage/AnimationUpload.tsx (1)

5-5: Ownership gating correctly migrated to MomentProvider

Deriving isOwner from useMomentProvider keeps the upload/reset enablement logic intact and consistent with the new context. No further changes needed here.

Also applies to: 11-11

components/TokenManagePage/Media.tsx (1)

4-4: Media component successfully re‑wired to MomentProvider

Switching to useMomentProvider for metadata, isOwner, and isLoading is consistent with the new moment-based flow and preserves the existing UX (skeleton, disabled fields, etc.). Looks good.

Also applies to: 16-16

components/TokenPage/TokenPage.tsx (1)

5-5: Moment object wiring and provider hierarchy look consistent

Constructing moment from the route params and passing it into MomentProvider matches the new Moment shape, and the provider wrapping order remains clear and predictable for descendants like Token, comments, and collect components.

Also applies to: 21-25, 30-37

components/TokenManagePage/AirdropButton.tsx (1)

3-3: Airdrop authorization correctly migrated to MomentProvider

Reading owner and tokenAdmins from useMomentProvider maintains the existing canAirdrop checks without changing semantics. No additional changes required here.

Also applies to: 8-8

components/TokenManagePage/TokenManagePage.tsx (1)

8-8: TokenManagePage correctly migrated to MomentProvider with Moment shape

Passing { collectionAddress: collection.address, tokenId, chainId: collection.chainId } into MomentProvider cleanly aligns manage flows (overview, airdrop, sale, media) with the new moment-based context. The surrounding logic stays unchanged and coherent.

Also applies to: 20-25, 37-37

components/TokenManagePage/SaveMediaButton.tsx (1)

2-2: SaveMediaButton ownership check correctly uses MomentProvider

Sourcing isOwner from useMomentProvider and reusing it in the disabled logic preserves the previous access control semantics while aligning with the new provider.

Also applies to: 9-9

components/TokenManagePage/OwnerWarning.tsx (1)

2-9: OwnerWarning correctly migrated to MomentProvider

Using useMomentProvider and destructuring isOwner is consistent with the new context API; no behavioral change introduced.

lib/moment/collectMoment.ts (1)

7-53: Verify moment.chainId presence and consistency with CHAIN_ID

The switch to getMomentOnChainInfo with

const { saleConfig } = await getMomentOnChainInfo({
  ...moment,
  collectionAddress: moment.collectionAddress as Address,
});

assumes that moment always contains a valid numeric chainId compatible with getPublicClient(chainId), while the rest of this function (split distribution and returned chainId) still relies on the global CHAIN_ID.

Please double‑check:

  • collectSchema guarantees moment.chainId exists and is a number.
  • moment.chainId is intended to always match CHAIN_ID here, or else update the later usage to stay on the same chain as the on‑chain fetch.

If multi‑chain support is expected, aligning CHAIN_ID versus moment.chainId in this flow will avoid subtle mismatches.

lib/moment/indexMoment.ts (1)

5-13: Indexing call correctly updated to getMomentOnChainInfo

The new getMomentOnChainInfo usage with { collectionAddress: address, tokenId: tokenId.toString(), chainId } matches the Moment shape and preserves the existing uri/admin mapping.

lib/mux/migrateMuxToArweave.ts (1)

6-51: migrateMuxToArweave correctly switched to getMomentOnChainInfo

The helper is now called with an object { collectionAddress, tokenId, chainId: CHAIN_ID }, which matches the new function signature while preserving the prior single‑chain behavior.

hooks/useMoment.ts (1)

12-18: LGTM!

The useQuery configuration is well-structured with appropriate stale time, retry logic, and enabled condition.

hooks/useMomentCollect.ts (1)

51-71: LGTM!

The branching logic for free vs. paid mints is clear, and the migration to use moment.collectionAddress and moment.tokenId is correctly implemented.

app/api/moment/route.ts (2)

30-36: LGTM!

The Moment object construction is clean, with proper address normalization via getAddress and chainId parsing. Schema validation upstream ensures the values are valid.


9-28: LGTM!

The request validation using Zod schema with detailed error responses is a solid pattern. The error details include field-level information which aids debugging.

Comment on lines +8 to +9
const useMoment = (moment: Moment) => {
const { collectionAddress, tokenId, chainId } = moment;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Potential runtime error if moment is undefined.

The destructuring on line 9 will throw if moment is undefined or null, even though the enabled condition on line 15 tries to guard against missing fields. Consider adding a defensive check or ensuring the hook is only called with a valid Moment object.

 const useMoment = (moment: Moment) => {
-  const { collectionAddress, tokenId, chainId } = moment;
+  const { collectionAddress, tokenId, chainId } = moment ?? {};

Alternatively, if the caller must always provide a valid Moment, enforce this at the call site and document the expectation.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const useMoment = (moment: Moment) => {
const { collectionAddress, tokenId, chainId } = moment;
const useMoment = (moment: Moment) => {
const { collectionAddress, tokenId, chainId } = moment ?? {};
🤖 Prompt for AI Agents
In hooks/useMoment.ts around lines 8 to 9, the direct destructuring const {
collectionAddress, tokenId, chainId } = moment will throw if moment is
undefined/null; add a defensive check before destructuring (e.g., guard early
return when moment is falsy) or change the hook signature to accept moment?:
Moment and handle the undefined case explicitly so downstream logic that relies
on those values only runs when moment is valid; alternatively enforce and
document that callers must pass a valid Moment and add a runtime assertion at
the top of the hook to fail fast with a clear message.

@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# First, let's find and read hooks/useSaleConfig.ts
echo "=== Reading hooks/useSaleConfig.ts ==="
fd -t f "useSaleConfig.ts" -x cat -n {}

echo
echo "=== File size check ==="
wc -l hooks/useSaleConfig.ts 2>/dev/null || echo "File not found yet, searching..."

Repository: sweetmantech/in_process

Length of output: 2793


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Searching for remaining TokenProvider usages ==="
rg -n "useTokenProvider|TokenProvider" --type ts --type tsx

echo
echo "=== Searching for tokenContractAddress references ==="
rg -n "tokenContractAddress" --type ts --type tsx

echo
echo "=== Finding and reading MomentProvider ==="
fd -t f "MomentProvider" -x cat -n {}

Repository: sweetmantech/in_process

Length of output: 164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Searching for remaining TokenProvider usages ==="
rg -n "useTokenProvider|TokenProvider" --type typescript

echo
echo "=== Searching for tokenContractAddress references ==="
rg -n "tokenContractAddress" --type typescript

echo
echo "=== Finding and reading MomentProvider ==="
fd -t f "MomentProvider" -x wc -l {}
fd -t f "MomentProvider" -x head -80 {}

Repository: sweetmantech/in_process

Length of output: 171


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Searching for remaining TokenProvider usages ==="
rg -n "useTokenProvider|TokenProvider"

echo
echo "=== Searching for tokenContractAddress references ==="
rg -n "tokenContractAddress"

echo
echo "=== Finding MomentProvider ==="
fd -t f "MomentProvider"

Repository: sweetmantech/in_process

Length of output: 119


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Searching for tokenContractAddress references ==="
rg -n "tokenContractAddress" 2>&1 | head -20

echo
echo "=== Finding MomentProvider files ==="
fd -t f "MomentProvider"

echo
echo "=== Searching for providers directory ==="
fd -t d "providers" | head -5

echo
echo "=== List providers files ==="
ls -la providers/ 2>/dev/null || echo "providers directory not found"

Repository: sweetmantech/in_process

Length of output: 3514


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Reading MomentProvider.tsx ==="
cat -n providers/MomentProvider.tsx

echo
echo "=== Reading types/token.ts ==="
cat -n types/token.ts

echo
echo "=== Context around useShareMoment.ts line 12 ==="
sed -n '1,20p' hooks/useShareMoment.ts | cat -n

Repository: sweetmantech/in_process

Length of output: 3083


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Finding and reading useMoment hook ==="
fd -t f "useMoment.ts" -o "useMoment.tsx" | head -1 | xargs wc -l

echo
fd -t f "useMoment.ts" -o "useMoment.tsx" | head -1 | xargs head -100

Repository: sweetmantech/in_process

Length of output: 274


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Finding useMoment hook ==="
fd "useMoment" hooks/

echo
echo "=== Reading useMoment hook ==="
fd "useMoment" hooks/ -x cat -n {}

Repository: sweetmantech/in_process

Length of output: 20305


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Checking types/moment.ts for Moment structure ==="
cat -n types/moment.ts

echo
echo "=== Full context of useSaleConfig.ts around token usage ==="
cat -n hooks/useSaleConfig.ts

Repository: sweetmantech/in_process

Length of output: 4412


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Check MomentProvider return type again - what does useMomentProvider return? ==="
sed -n '28,34p' providers/MomentProvider.tsx

echo
echo "=== Check useMoment return statement ==="
sed -n '34,53p' hooks/useMoment.ts

echo
echo "=== Verify: does useMomentProvider return moment? ==="
sed -n '13,26p' providers/MomentProvider.tsx

Repository: sweetmantech/in_process

Length of output: 1248


Fix critical bug: useSaleConfig references non-existent token field from useMomentProvider

The main issue is that useSaleConfig is trying to destructure a token field that does not exist in useMomentProvider(). The provider returns moment, saleConfig, metadata, and other fields—but no token.

Additionally, consolidate the two useMomentProvider() calls into one. Here's the corrected approach:

 const useSaleConfig = () => {
-  const { saleConfig: sale } = useMomentProvider();
+  const { saleConfig: sale, moment, fetchTokenInfo } = useMomentProvider();
   const [saleStart, setSaleStart] = useState<Date>(new Date());
-  const { token, fetchTokenInfo } = useMomentProvider();
   const { signTransaction } = useSignTransaction();
   const { connectedAddress } = useUserProvider();
   const [isLoading, setIsLoading] = useState<boolean>(false);

   const setSale = async () => {
     if (!sale) return;
     setIsLoading(true);
     const newSale = {
       ...sale,
       saleStart: BigInt(Number(saleStart.getTime() / 1000).toFixed(0)),
     };
     const calldata = encodeFunctionData({
       abi: zoraCreatorFixedPriceSaleStrategyABI,
       functionName: "setSale",
-      args: [BigInt(token.tokenId), newSale],
+      args: [BigInt(moment.tokenId), newSale],
     });
     const publicClient = getPublicClient(CHAIN_ID);
     const hash = await signTransaction({
-      address: token.tokenContractAddress,
+      address: moment.collectionAddress,
       abi: zoraCreator1155ImplABI,
       functionName: "callSale",
-      args: [token.tokenId, zoraCreatorFixedPriceSaleStrategyAddress[CHAIN_ID], calldata],
+      args: [moment.tokenId, zoraCreatorFixedPriceSaleStrategyAddress[CHAIN_ID], calldata],
       account: connectedAddress as Address,
       chain: CHAIN,
     });

The moment object (available from useMomentProvider) has collectionAddress and tokenId fields—use those instead of the non-existent token object.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useMomentProvider } from "@/providers/MomentProvider";
const useSaleConfig = () => {
const { saleConfig: sale, moment, fetchTokenInfo } = useMomentProvider();
const [saleStart, setSaleStart] = useState<Date>(new Date());
const { signTransaction } = useSignTransaction();
const { connectedAddress } = useUserProvider();
const [isLoading, setIsLoading] = useState<boolean>(false);
const setSale = async () => {
if (!sale) return;
setIsLoading(true);
const newSale = {
...sale,
saleStart: BigInt(Number(saleStart.getTime() / 1000).toFixed(0)),
};
const calldata = encodeFunctionData({
abi: zoraCreatorFixedPriceSaleStrategyABI,
functionName: "setSale",
args: [BigInt(moment.tokenId), newSale],
});
const publicClient = getPublicClient(CHAIN_ID);
const hash = await signTransaction({
address: moment.collectionAddress,
abi: zoraCreator1155ImplABI,
functionName: "callSale",
args: [moment.tokenId, zoraCreatorFixedPriceSaleStrategyAddress[CHAIN_ID], calldata],
account: connectedAddress as Address,
chain: CHAIN,
});
🤖 Prompt for AI Agents
In hooks/useSaleConfig.ts around line 2, the hook incorrectly destructures a
non-existent token field from useMomentProvider() and calls useMomentProvider()
twice; update the code to call useMomentProvider() once, remove token from the
destructure, and replace any token.* usage with moment.collectionAddress and
moment.tokenId (or equivalent fields) so the hook uses the actual fields
returned by the provider.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/api/moment/route.ts (1)

54-54: Use unknown instead of any for caught errors.

Per strict TypeScript guidelines, prefer unknown and narrow the type safely.

-  } catch (error: any) {
+  } catch (error: unknown) {
     console.error("Error fetching moment info:", error);
+    const message = error instanceof Error ? error.message : "Failed to fetch moment info";
     return NextResponse.json(
-      { error: error?.message || "Failed to fetch moment info" },
+      { error: message },
       { status: 500 }
     );
   }
♻️ Duplicate comments (1)
hooks/useSaleConfig.ts (1)

15-17: Consolidate duplicate useMomentProvider() calls.

The hook calls useMomentProvider() twice (lines 15 and 17), which is inefficient and violates DRY principles.

Consolidate into a single call:

-  const { saleConfig: sale } = useMomentProvider();
+  const { saleConfig: sale, moment, fetchTokenInfo } = useMomentProvider();
   const [saleStart, setSaleStart] = useState<Date>(new Date());
-  const { moment, fetchTokenInfo } = useMomentProvider();
🧹 Nitpick comments (12)
hooks/useAirdrop.ts (1)

19-20: Consider clearer variable naming.

The destructuring renames collectionAddress to momentContract, which adds an unnecessary layer of indirection. Consider using the property name directly or use a more descriptive variable name.

Apply this diff for clearer naming:

-  const { moment } = useMomentProvider();
-  const { collectionAddress: momentContract, tokenId } = moment;
+  const { moment } = useMomentProvider();
+  const { collectionAddress, tokenId } = moment;

Then update line 70:

-        momentContract,
+        collectionAddress,
lib/moment/momentComments.ts (1)

15-15: Use consistent camelCase naming convention.

The variable momentdata doesn't follow camelCase convention. Consider renaming to momentData for consistency with TypeScript/JavaScript naming standards.

Apply this diff:

-  const momentdata = await selectMoment({
+  const momentData = await selectMoment({
     collectionAddress: moment.contractAddress as Address,
     tokenId: moment.tokenId,
     chainId,
   });
 
-  if (!momentdata) {
+  if (!momentData) {
     throw new Error("Moment not found");
   }
 
   const comments = await selectComments({
-    momentId: momentdata.id,
+    momentId: momentData.id,
     offset,
   });

Also applies to: 21-21, 26-26

hooks/useBalanceOf.ts (1)

2-26: Consider adding error handling around readContract

The shift to useMomentProvider and use of moment.collectionAddress / moment.tokenId looks correct, but readContract failures will currently surface as unhandled promise rejections from the effect. Wrapping the call in a try/catch (and maybe logging or defaulting balanceOf to 0) would make this hook more resilient.

lib/zora/getSalesConfig.tsx (1)

4-38: Switching to MomentType enums is fine; consider tightening saleStrategy type

Using MomentType.FixedPriceMint/TimedMint/Erc20Mint keeps behavior intact. To avoid invalid values slipping through, consider updating the saleStrategy parameter type to MomentType (or a union of the specific members used) instead of plain string.

lib/sales/convertDatabaseSaleToApi.ts (2)

10-10: Unsafe cast of funds_recipient to Address.

The string is cast to Address without validation. If the database contains an invalid address format, this could cause issues downstream.

Consider using viem's isAddress for validation:

+import { Address, zeroAddress, isAddress } from "viem";
...
-  fundsRecipient: sale.funds_recipient as Address,
+  fundsRecipient: isAddress(sale.funds_recipient) ? sale.funds_recipient : zeroAddress,

Alternatively, if you trust the database integrity, the current approach is acceptable.


7-8: Redundant Number() calls on already-numeric types.

DatabaseSale defines sale_start, sale_end, and max_tokens_per_address as number types. The Number() wrapper is unnecessary.

-  saleStart: Number(sale.sale_start),
-  saleEnd: Number(sale.sale_end),
-  maxTokensPerAddress: Number(sale.max_tokens_per_address),
+  saleStart: sale.sale_start,
+  saleEnd: sale.sale_end,
+  maxTokensPerAddress: sale.max_tokens_per_address,
lib/moment/getMomentAdvancedInfo.ts (2)

4-4: Confusing import path vs function name.

The function getMomentOnChainInfo is imported from "@/lib/viem/getTokenInfo". This naming mismatch between the file and the exported function can cause confusion. Based on the AI summary, this was renamed from getTokenInfo but the file wasn't renamed.

Consider renaming the file to match the function name for consistency:

  • Rename lib/viem/getTokenInfo.tslib/viem/getMomentOnChainInfo.ts

8-42: Consider adding error handling for failed data fetches.

The function has no try-catch blocks. If selectMoment, selectSale, or getMomentOnChainInfo throw, the error propagates directly. Depending on how this is used, you may want to return a null/partial result instead.

If graceful degradation is desired:

 export const getMomentAdvancedInfo = async (moment: Moment): Promise<MomentAdvancedInfo> => {
+  try {
     const momentdata = await selectMoment(moment);
     // ... rest of logic
+  } catch (error) {
+    console.error("Failed to get moment advanced info:", error);
+    return { uri: null, owner: null, saleConfig: null };
+  }
 };

Otherwise, if letting errors propagate is intentional, this is acceptable.

lib/moment/collectMoment.ts (1)

7-7: Import path naming inconsistency.

Same issue as in getMomentAdvancedInfo.ts - importing getMomentOnChainInfo from a file named getTokenInfo. Consider renaming the file for clarity.

lib/viem/getTokenInfo.ts (2)

11-12: Combine imports from the same module.

-import { MomentType } from "@/types/moment";
-import { Moment } from "@/types/moment";
+import { Moment, MomentType } from "@/types/moment";

49-58: Add null safety checks for multicall results.

If any multicall fails, accessing .result on undefined could cause runtime errors. Consider defensive checks before accessing nested properties.

+  const erc20Result = infoCalls[0]?.result;
+  const fixedResult = infoCalls[1]?.result;
+
   const saleConfig =
-    infoCalls[0]?.result?.saleEnd > BigInt(0)
+    erc20Result?.saleEnd && erc20Result.saleEnd > BigInt(0)
       ? {
-          ...infoCalls[0]?.result,
+          ...erc20Result,
           type: MomentType.Erc20Mint,
         }
       : {
-          ...infoCalls[1]?.result,
+          ...fixedResult,
           type: MomentType.FixedPriceMint,
         };
app/api/moment/route.ts (1)

38-38: Handle missing URI more explicitly.

Passing an empty string to fetchTokenMetadata when uri is undefined may lead to failed fetches or unexpected behavior. Consider returning early or providing a more meaningful fallback.

+    if (!uri) {
+      return NextResponse.json(
+        { error: "Moment URI not found" },
+        { status: 404 }
+      );
+    }
+
-    const metadata = await fetchTokenMetadata(uri || "");
+    const metadata = await fetchTokenMetadata(uri);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bdc481a and 29e859a.

📒 Files selected for processing (46)
  • app/api/moment/route.ts (2 hunks)
  • app/api/moment/update-uri/route.ts (1 hunks)
  • app/api/og/artist/route.tsx (2 hunks)
  • app/api/og/token/route.tsx (2 hunks)
  • components/ArtSlider/CarouselItem.tsx (2 hunks)
  • components/CollectionManagePage/CollectionOverview.tsx (2 hunks)
  • components/CreatedMoment/CreatedMomentAirdrop.tsx (1 hunks)
  • components/HorizontalFeed/FeedHover.tsx (1 hunks)
  • components/Renderers/ContentRenderer.tsx (1 hunks)
  • hooks/useAirdrop.ts (1 hunks)
  • hooks/useBalanceOf.ts (1 hunks)
  • hooks/useCollectBalanceValidation.ts (2 hunks)
  • hooks/useCollection.ts (1 hunks)
  • hooks/useComments.ts (1 hunks)
  • hooks/useMediaInitialization.ts (1 hunks)
  • hooks/useMetadata.ts (1 hunks)
  • hooks/useSaleConfig.ts (3 hunks)
  • hooks/useShareMoment.ts (1 hunks)
  • lib/fetchArtistLatestMint.ts (1 hunks)
  • lib/fetchTokenMetadata.ts (1 hunks)
  • lib/getArtistLatestMoment.ts (1 hunks)
  • lib/getPrice.ts (1 hunks)
  • lib/getPriceUnit.ts (1 hunks)
  • lib/getSaleConfigType.ts (1 hunks)
  • lib/moment/collectMoment.ts (3 hunks)
  • lib/moment/fetchComments.ts (1 hunks)
  • lib/moment/getMomentAdvancedInfo.ts (1 hunks)
  • lib/moment/momentComments.ts (2 hunks)
  • lib/moment/validateBalanceAndAllowance.ts (2 hunks)
  • lib/sales/convertDatabaseSaleToApi.ts (1 hunks)
  • lib/sales/convertOnChainSaleToApi.ts (1 hunks)
  • lib/supabase/in_process_admins/selectAdmins.ts (1 hunks)
  • lib/supabase/in_process_moments/selectMoment.ts (2 hunks)
  • lib/supabase/in_process_sales/selectSale.ts (1 hunks)
  • lib/supabase/in_process_tokens/selectInProcessToken.ts (0 hunks)
  • lib/viem/getCollectCall.ts (2 hunks)
  • lib/viem/getNextTokenIds.ts (0 hunks)
  • lib/viem/getTokenInfo.ts (4 hunks)
  • lib/zora/getSalesConfig.tsx (2 hunks)
  • types/dune.ts (0 hunks)
  • types/fetch-collections.ts (0 hunks)
  • types/jam.ts (0 hunks)
  • types/moment.ts (2 hunks)
  • types/sale.ts (1 hunks)
  • types/token.ts (0 hunks)
  • types/zora.ts (0 hunks)
💤 Files with no reviewable changes (7)
  • types/jam.ts
  • types/dune.ts
  • lib/supabase/in_process_tokens/selectInProcessToken.ts
  • types/token.ts
  • types/fetch-collections.ts
  • lib/viem/getNextTokenIds.ts
  • types/zora.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Minimize code to absolute minimum needed - avoid unnecessary abstractions, intermediate steps, or redundant patterns
Write self-documenting code through precise naming (verbs for functions, nouns for variables), single-responsibility components, obvious data flow, and add short comments only when necessary
Apply Single Responsibility Principle (SRP): each function/component should have ONE clear responsibility - extract functions into separate files when they handle distinct concerns - hooks focus on state management, business logic goes in lib files - each function should be in its own file when it has a distinct purpose
Use strict TypeScript types with zero 'any' - prioritize type-exact definitions
Implement built-in security for authentication and data handling - follow secure coding practices throughout the application
Follow Next.js optimization guides for performance - implement proper caching, code splitting, and rendering strategies
Keep all files under 100 lines of code to maintain readability and follow single responsibility principle - split hooks/components when they grow too large or handle multiple concerns
Before coding, make a plan inside a tag: identify core requirement, consider 3 implementation approaches, choose simplest that meets needs, verify if code can be split into smaller functions, check for unnecessary abstractions, and ensure clarity for junior developers

Files:

  • components/CreatedMoment/CreatedMomentAirdrop.tsx
  • lib/moment/momentComments.ts
  • lib/getPrice.ts
  • lib/moment/validateBalanceAndAllowance.ts
  • hooks/useMediaInitialization.ts
  • lib/getArtistLatestMoment.ts
  • lib/supabase/in_process_admins/selectAdmins.ts
  • types/sale.ts
  • hooks/useShareMoment.ts
  • hooks/useAirdrop.ts
  • hooks/useCollection.ts
  • hooks/useCollectBalanceValidation.ts
  • lib/getPriceUnit.ts
  • hooks/useMetadata.ts
  • lib/sales/convertDatabaseSaleToApi.ts
  • app/api/moment/update-uri/route.ts
  • components/CollectionManagePage/CollectionOverview.tsx
  • lib/sales/convertOnChainSaleToApi.ts
  • components/HorizontalFeed/FeedHover.tsx
  • app/api/og/token/route.tsx
  • lib/fetchArtistLatestMint.ts
  • lib/moment/getMomentAdvancedInfo.ts
  • app/api/moment/route.ts
  • lib/fetchTokenMetadata.ts
  • hooks/useBalanceOf.ts
  • components/Renderers/ContentRenderer.tsx
  • lib/supabase/in_process_sales/selectSale.ts
  • lib/moment/collectMoment.ts
  • hooks/useSaleConfig.ts
  • lib/supabase/in_process_moments/selectMoment.ts
  • lib/moment/fetchComments.ts
  • lib/viem/getTokenInfo.ts
  • lib/zora/getSalesConfig.tsx
  • components/ArtSlider/CarouselItem.tsx
  • lib/getSaleConfigType.ts
  • app/api/og/artist/route.tsx
  • lib/viem/getCollectCall.ts
  • hooks/useComments.ts
  • types/moment.ts
lib/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Library files should contain pure business logic, data transformation, validation, and API calls - never include React state management or UI concerns

Files:

  • lib/moment/momentComments.ts
  • lib/getPrice.ts
  • lib/moment/validateBalanceAndAllowance.ts
  • lib/getArtistLatestMoment.ts
  • lib/supabase/in_process_admins/selectAdmins.ts
  • lib/getPriceUnit.ts
  • lib/sales/convertDatabaseSaleToApi.ts
  • lib/sales/convertOnChainSaleToApi.ts
  • lib/fetchArtistLatestMint.ts
  • lib/moment/getMomentAdvancedInfo.ts
  • lib/fetchTokenMetadata.ts
  • lib/supabase/in_process_sales/selectSale.ts
  • lib/moment/collectMoment.ts
  • lib/supabase/in_process_moments/selectMoment.ts
  • lib/moment/fetchComments.ts
  • lib/viem/getTokenInfo.ts
  • lib/zora/getSalesConfig.tsx
  • lib/getSaleConfigType.ts
  • lib/viem/getCollectCall.ts
hooks/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Hooks should focus exclusively on state management and data fetching - extract business logic, validation, and data transformation into separate lib files

Files:

  • hooks/useMediaInitialization.ts
  • hooks/useShareMoment.ts
  • hooks/useAirdrop.ts
  • hooks/useCollection.ts
  • hooks/useCollectBalanceValidation.ts
  • hooks/useMetadata.ts
  • hooks/useBalanceOf.ts
  • hooks/useSaleConfig.ts
  • hooks/useComments.ts
🧬 Code graph analysis (26)
components/CreatedMoment/CreatedMomentAirdrop.tsx (3)
providers/MomentCreateProvider/MomentCreateProvider.tsx (1)
  • useMomentCreateProvider (31-31)
providers/MomentProvider.tsx (1)
  • MomentProvider (13-26)
lib/consts.ts (1)
  • CHAIN_ID (20-20)
hooks/useMediaInitialization.ts (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
lib/getArtistLatestMoment.ts (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
lib/supabase/in_process_admins/selectAdmins.ts (2)
types/moment.ts (1)
  • Moment (4-8)
lib/supabase/client.ts (1)
  • supabase (7-7)
hooks/useAirdrop.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
hooks/useCollection.ts (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
hooks/useMetadata.ts (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
lib/sales/convertDatabaseSaleToApi.ts (2)
types/sale.ts (1)
  • DatabaseSale (13-20)
types/moment.ts (1)
  • MomentApiSaleConfig (80-87)
components/CollectionManagePage/CollectionOverview.tsx (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
lib/sales/convertOnChainSaleToApi.ts (2)
types/sale.ts (1)
  • OnChainSaleConfig (4-11)
types/moment.ts (1)
  • MomentApiSaleConfig (80-87)
components/HorizontalFeed/FeedHover.tsx (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
lib/fetchArtistLatestMint.ts (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
lib/moment/getMomentAdvancedInfo.ts (3)
types/moment.ts (2)
  • Moment (4-8)
  • MomentAdvancedInfo (97-101)
lib/sales/convertDatabaseSaleToApi.ts (1)
  • convertDatabaseSaleToApi (5-15)
lib/sales/convertOnChainSaleToApi.ts (1)
  • convertOnChainSaleToApi (4-11)
app/api/moment/route.ts (2)
types/moment.ts (1)
  • Moment (4-8)
lib/moment/getMomentAdvancedInfo.ts (1)
  • getMomentAdvancedInfo (8-42)
lib/fetchTokenMetadata.ts (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
hooks/useBalanceOf.ts (3)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
providers/UserProvider.tsx (1)
  • useUserProvider (38-44)
lib/viem/publicClient.ts (2)
  • publicClient (16-16)
  • getPublicClient (7-14)
components/Renderers/ContentRenderer.tsx (1)
types/moment.ts (1)
  • MomentMetadata (62-72)
lib/supabase/in_process_sales/selectSale.ts (1)
lib/supabase/client.ts (1)
  • supabase (7-7)
lib/moment/collectMoment.ts (2)
lib/moment/validateBalanceAndAllowance.ts (1)
  • validateBalanceAndAllowance (15-40)
lib/consts.ts (1)
  • USDC_ADDRESS (32-34)
hooks/useSaleConfig.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
lib/supabase/in_process_moments/selectMoment.ts (1)
types/moment.ts (1)
  • Moment (4-8)
lib/moment/fetchComments.ts (1)
types/moment.ts (2)
  • MomentCommentsInput (10-13)
  • MintComment (26-32)
lib/viem/getTokenInfo.ts (3)
types/moment.ts (1)
  • Moment (4-8)
lib/viem/publicClient.ts (2)
  • publicClient (16-16)
  • getPublicClient (7-14)
lib/protocolSdk/constants.ts (1)
  • erc20MinterAddresses (70-83)
components/ArtSlider/CarouselItem.tsx (2)
types/moment.ts (1)
  • MomentMetadata (62-72)
app/page.tsx (1)
  • metadata (8-34)
app/api/og/artist/route.tsx (1)
app/page.tsx (1)
  • metadata (8-34)
hooks/useComments.ts (1)
providers/MomentProvider.tsx (1)
  • useMomentProvider (28-34)
🔇 Additional comments (31)
hooks/useCollection.ts (1)

2-2: LGTM! Clean type migration.

The type changes from Metadata to MomentMetadata are consistent with the moment-centric refactor and align with the new type definition in types/moment.ts.

Also applies to: 7-7

hooks/useMediaInitialization.ts (1)

2-2: LGTM! Type migration is correct.

The parameter type update to MomentMetadata aligns with the broader refactor and maintains compatibility with the existing initialization logic.

Also applies to: 5-5

components/CreatedMoment/CreatedMomentAirdrop.tsx (1)

6-6: LGTM! Provider migration correctly implemented.

The transition from TokenProvider to MomentProvider is properly structured with the correct moment object shape containing collectionAddress, tokenId, and chainId. The Address type assertion on Line 18 is appropriate.

Also applies to: 8-8, 16-24

hooks/useCollectBalanceValidation.ts (1)

2-2: LGTM! Enum migration is correct.

The update from MintType to MomentType aligns with the codebase-wide refactor. The balance validation logic remains unchanged.

Also applies to: 14-14

lib/viem/getCollectCall.ts (1)

5-5: LGTM! Enum reference correctly updated.

The change from MintType.Erc20Mint to MomentType.Erc20Mint is consistent with the moment-centric refactor. The function logic and ABI encoding remain unchanged.

Also applies to: 25-25

lib/moment/validateBalanceAndAllowance.ts (1)

9-9: LGTM! Enum migration is correct.

The update to MomentType.Erc20Mint maintains the existing validation logic while aligning with the moment-centric type system.

Also applies to: 21-21

app/api/moment/update-uri/route.ts (1)

40-40: Schema alignment verified—collectionAddress is properly defined in momentSchema.

The updateMomentURISchema correctly uses momentSchema from lib/schema/collectSchema.ts, which includes the collectionAddress field as an addressSchema type. The property change from contractAddress to collectionAddress is fully supported by the schema validation, confirming the moment-centric refactor is consistent throughout the validation layer.

lib/getArtistLatestMoment.ts (1)

1-1: Type consistency verified — no issues found.

The fetchTokenMetadata function in lib/fetchTokenMetadata.ts (line 7) correctly returns Promise<MomentMetadata | null>, which aligns with:

  • The MomentMetadata import from @/types/moment (line 1)
  • The return type of getArtistLatestMoment function (line 8 in lib/getArtistLatestMoment.ts)

Type consistency is maintained across both functions.

components/CollectionManagePage/CollectionOverview.tsx (1)

5-5: LGTM!

The type migration from Metadata to MomentMetadata is correctly applied and aligns with the PR's objective to migrate to moment-centric data flow.

Also applies to: 42-42

lib/supabase/in_process_sales/selectSale.ts (1)

3-11: LGTM!

The function implementation is clean and follows the single responsibility principle. Returning null on error is an acceptable pattern for optional data retrieval.

app/api/og/artist/route.tsx (1)

41-41: LGTM!

The addition of optional chaining for metadata.content?.mime is a good defensive programming practice that aligns with the MomentMetadata interface where content is optional. This prevents potential runtime errors when content is undefined or null.

Also applies to: 88-88

hooks/useMetadata.ts (1)

2-2: LGTM!

The type migration from Metadata to MomentMetadata is correctly applied throughout the function signature and aligns with the PR's moment-centric refactoring.

Also applies to: 5-5

lib/fetchTokenMetadata.ts (1)

1-1: LGTM!

The type migration to MomentMetadata is correct. Note that the function name fetchTokenMetadata still references "token" while returning MomentMetadata, but this is acceptable given it's fetching metadata for NFT tokens.

Also applies to: 7-7

components/Renderers/ContentRenderer.tsx (1)

3-3: LGTM!

The type migration from Metadata to MomentMetadata in the component props and import is correctly applied. All property accesses remain compatible with the new type structure.

Also applies to: 11-11

hooks/useComments.ts (1)

10-78: LGTM! Clean migration to MomentProvider.

The hook successfully migrates to the moment-based data model while maintaining clean state management patterns. The pagination implementation, optimistic updates, and memoization are well-structured.

lib/supabase/in_process_moments/selectMoment.ts (1)

4-23: LGTM! Clean refactor to moment-based signature.

The migration to a single Moment parameter and the use of .single() for fetching a single record are appropriate improvements. Error handling with null return is consistent with the new pattern.

types/moment.ts (1)

4-101: LGTM! Well-structured type definitions.

The moment-centric types are well-defined with proper TypeScript strictness. The renaming from contractAddress to collectionAddress and addition of chainId align with the broader migration to moment-based data flow.

lib/getPrice.ts (1)

1-7: LGTM! Clean type migration.

The migration from MintType to MomentType is straightforward and preserves the existing logic correctly.

lib/getPriceUnit.ts (1)

1-6: LGTM! Consistent type migration.

The migration from MintType to MomentType maintains the existing behavior correctly.

hooks/useShareMoment.ts (1)

6-19: LGTM! Clean provider migration.

The hook successfully migrates to useMomentProvider while maintaining its focused responsibility of sharing moment URLs. The field mappings to collectionAddress and tokenId are correct.

components/ArtSlider/CarouselItem.tsx (1)

2-41: MomentMetadata swap and safer content access look correct

Using MomentMetadata and metadata.content?.mime/uri aligns with the new type and avoids runtime errors when content is null, while preserving existing rendering branches.

components/HorizontalFeed/FeedHover.tsx (1)

3-19: FeedHover props now correctly use MomentMetadata

The prop type and import update to MomentMetadata are consistent with the new data model; runtime behavior remains the same.

lib/fetchArtistLatestMint.ts (1)

1-18: Return type alignment with MomentMetadata is appropriate

Updating getArtistLatestMint to return Promise<MomentMetadata | null> matches the new metadata shape without changing the existing fetch logic.

app/api/og/token/route.tsx (1)

35-47: Optional chaining for metadata.content is a safe improvement

Using metadata.content?.mime and metadata.content?.uri correctly guards against missing content while keeping the writing/image branches unchanged.

lib/getSaleConfigType.ts (1)

1-7: MomentType mapping in getSaleConfigType looks correct

The function now cleanly maps the three string values to the corresponding MomentType enum members; no behavior regressions apparent.

lib/sales/convertOnChainSaleToApi.ts (1)

4-11: LGTM!

Clean utility function with correct type conversions. The bigint to Number conversions for timestamps are safe for realistic Unix timestamps. The implementation follows the single-responsibility principle for lib files.

types/sale.ts (1)

1-20: LGTM!

Well-structured type definitions with clear separation between on-chain (bigint for blockchain values) and database representations. The snake_case naming for DatabaseSale correctly reflects typical database column conventions.

lib/moment/collectMoment.ts (2)

71-71: LGTM on MomentType usage.

The switch from MintType to MomentType.Erc20Mint is consistent with the usage in validateBalanceAndAllowance.ts (per the code snippet).


38-41: Redundant spread and cast is confirmed—simplify to pass moment directly.

The getMomentOnChainInfo function (line 14 in lib/viem/getTokenInfo.ts) expects a Moment type parameter directly. Since Moment.collectionAddress is already typed as Address in types/moment.ts, the spread with explicit override adds no value and introduces unnecessary complexity.

-  const { saleConfig } = await getMomentOnChainInfo({
-    ...moment,
-    collectionAddress: moment.collectionAddress as Address,
-  });
+  const { saleConfig } = await getMomentOnChainInfo(moment);

This refactor maintains type safety while improving clarity.

lib/viem/getTokenInfo.ts (1)

21-21: Verify tokenId type compatibility with ABI expectations.

The tokenId is passed as a string, but ERC-1155 ABIs typically expect bigint for token ID arguments. This could cause runtime issues or incorrect encoding.

+  const tokenIdBigInt = BigInt(tokenId);
+
   const erc20SaleConfigCall = {
     address: erc20MinterAddresses[chainId as keyof typeof erc20MinterAddresses],
     abi: erc20MinterABI,
     functionName: "sale",
-    args: [collectionAddress, tokenId],
+    args: [collectionAddress, tokenIdBigInt],
   };
   const fixedSaleConfigCall = {
     ...
-    args: [collectionAddress, tokenId],
+    args: [collectionAddress, tokenIdBigInt],
   };
   const uriCall = {
     ...
-    args: [tokenId],
+    args: [tokenIdBigInt],
   };

Also applies to: 30-30, 36-36

app/api/moment/route.ts (1)

41-53: Response structure looks good for the moment-centric migration.

The response payload correctly includes uri, owner, saleConfig, momentAdmins, and enriched metadata fields, aligning with the refactored data flow.

Comment on lines +30 to 35
const { collectionAddress, tokenId, chainId } = parseResult.data;
const moment: Moment = {
collectionAddress: getAddress(collectionAddress),
tokenId,
chainId: parseInt(chainId, 10),
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for getMomentSchema definition
ast-grep --pattern 'getMomentSchema'

Repository: sweetmantech/in_process

Length of output: 321


🏁 Script executed:

#!/bin/bash
# Read the schema file to see chainId definition
cat -n lib/schema/getMomentSchema.ts

Repository: sweetmantech/in_process

Length of output: 609


🏁 Script executed:

#!/bin/bash
# Read the relevant sections of app/api/moment/route.ts
cat -n app/api/moment/route.ts | head -60

Repository: sweetmantech/in_process

Length of output: 2577


Based on my verification, I can now provide the rewritten review comment. The key finding is that the original review's concern about parseInt being redundant is incorrect — the schema explicitly returns chainId as a string, making the conversion necessary. However, there are two other valid concerns.

Remove the parseInt redundancy concern; focus on error typing violation and uri handling.

The schema defines chainId as z.string() with validation, so the parseInt(chainId, 10) conversion is necessary and correct. However, fix the error typing at line 54 (error: any should be error: unknown for strict TypeScript compliance), and the uri || "" fallback at line 38 could mask issues if fetchTokenMetadata expects a valid URI.

🤖 Prompt for AI Agents
In app/api/moment/route.ts around lines 30-35 and also referencing lines ~38 and
~54, the review wrongly flagged parseInt as redundant (it's needed because
schema returns chainId as string), but you must fix two real issues: replace the
error parameter type from `any` to `unknown` at line 54 and handle the `uri`
fallback at line 38 without silently passing an empty string. Change the catch
signature to `error: unknown` and narrow/format it before logging/responding;
for the URI, validate that `uri` is present and well-formed before calling
fetchTokenMetadata (return a 400 or handle missing/invalid URIs explicitly)
instead of using `uri || ""` which can mask errors.

} = await getMomentOnChainInfo(moment);
return {
uri: tokenUri,
owner: tokenOwner as string,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the getMomentAdvancedInfo.ts file and check its location
fd -t f "getMomentAdvancedInfo.ts" --type ts

Repository: sweetmantech/in_process

Length of output: 236


🏁 Script executed:

#!/bin/bash
# Find getMomentAdvancedInfo.ts file
fd "getMomentAdvancedInfo.ts"

# Also search for the specific file we know exists
find . -name "getMomentAdvancedInfo.ts" -type f

Repository: sweetmantech/in_process

Length of output: 140


🏁 Script executed:

#!/bin/bash
# Read the getMomentAdvancedInfo.ts file to see context around line 39
wc -l lib/moment/getMomentAdvancedInfo.ts
cat -n lib/moment/getMomentAdvancedInfo.ts

# Also search for getMomentOnChainInfo function definition
rg -n "getMomentOnChainInfo" --type-list | head -5
rg -n "getMomentOnChainInfo" -A 10 -B 2

Repository: sweetmantech/in_process

Length of output: 12624


🏁 Script executed:

#!/bin/bash
# Read the full getMomentOnChainInfo function in lib/viem/getTokenInfo.ts
cat -n lib/viem/getTokenInfo.ts

# Search for MomentAdvancedInfo type definition
rg -n "type MomentAdvancedInfo|interface MomentAdvancedInfo" -A 10

Repository: sweetmantech/in_process

Length of output: 2631


🏁 Script executed:

#!/bin/bash
# Check if there's any error handling around the multicall or owner property
rg -n "multicall|infoCalls\[3\]" lib/viem/getTokenInfo.ts -B 3 -A 3

# Check how tokenOwner is used in other places
rg -n "tokenOwner" lib/moment/ -B 2 -A 2

# Look for any null/undefined checks on owner in the codebase
rg -n "owner.*\?" types/moment.ts -B 5 -A 5

Repository: sweetmantech/in_process

Length of output: 1001


Add null check before casting tokenOwner to string.

The cast at line 39 (tokenOwner as string) suppresses type checking without validating that tokenOwner is not null. Since getMomentOnChainInfo returns owner: infoCalls[3].result from a smart contract multicall with no error handling, the result can be null or undefined if the call fails. MomentAdvancedInfo.owner accepts string | null, so either:

  1. Remove the cast and allow null (matches the type), or
  2. Add a null check: owner: tokenOwner ?? fallbackValue or owner: tokenOwner as string | null
🤖 Prompt for AI Agents
In lib/moment/getMomentAdvancedInfo.ts around line 39, the code casts tokenOwner
to string without checking for null which can hide a failed multicall result;
change the assignment so it does not force a non-null string: either remove the
cast and assign owner: tokenOwner allowing the declared type string | null, or
explicitly check and provide a fallback (e.g. owner: tokenOwner ?? null) so
null/undefined is handled safely instead of suppressed by a cast.

Comment on lines +4 to +11
const selectAdmins = async (moment: Moment) => {
const { data, error } = await supabase
.from("in_process_admins")
.select("*")
.eq("collection", moment.collectionAddress)
.or(`token_id.in.(0,${moment.tokenId})`);
if (error) return [];
return data || [];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, check the file structure and read the specific file
find . -name "selectAdmins.ts" -type f 2>/dev/null | head -5

Repository: sweetmantech/in_process

Length of output: 115


🏁 Script executed:

#!/bin/bash
# Read the file to see current implementation
wc -l ./lib/supabase/in_process_admins/selectAdmins.ts
cat -n ./lib/supabase/in_process_admins/selectAdmins.ts

Repository: sweetmantech/in_process

Length of output: 606


🏁 Script executed:

#!/bin/bash
# Check the Moment type to understand tokenId
fd -e ts -e tsx -e js | xargs grep -l "type Moment\|interface Moment" | head -5

Repository: sweetmantech/in_process

Length of output: 245


🏁 Script executed:

#!/bin/bash
# Read the Moment type definition
cat -n ./types/moment.ts

Repository: sweetmantech/in_process

Length of output: 2750


🏁 Script executed:

#!/bin/bash
# Search for Supabase query patterns - look for .in() and .or() usage
rg -n '\.(in|or)\s*\(' lib/supabase --type ts -A 2 -B 2 | head -60

Repository: sweetmantech/in_process

Length of output: 2270


🏁 Script executed:

#!/bin/bash
# Let's check the getInProcessTokens.ts file to understand .in() better
cat -n ./lib/supabase/in_process_tokens/getInProcessTokens.ts

Repository: sweetmantech/in_process

Length of output: 2434


🏁 Script executed:

#!/bin/bash
# Let me check if there's any documentation or usage showing why .or() was used vs .in()
# Check if there are any complex .or() patterns that justify the string approach
rg -n "\.or\(" lib/supabase --type ts -B 2 -A 2

Repository: sweetmantech/in_process

Length of output: 469


Based on my verification, I've confirmed the review comment's concerns are valid:

  1. Verified the pattern is anomalous: The codebase uses .in(field, array) consistently in 5+ other locations (getInProcessTokens, updateInProcessTokens, selectPayments, selectArtists), but selectAdmins.ts uniquely uses string interpolation in .or().

  2. Confirmed semantic equivalence: The suggested refactor from .or(\token_id.in.(0,${moment.tokenId})`)to.in("token_id", [0, Number(moment.tokenId)])` is semantically identical and achieves the same filtering logic.

  3. Validated tokenId type: tokenId is a string, and the suggested Number() conversion is appropriate.

  4. String interpolation risk: While the Supabase JS SDK likely provides escaping, the string interpolation approach is less robust and inconsistent with established patterns in this codebase.


Replace .or() string interpolation with parameterized .in() for consistency and safety

This is the only place in the Supabase lib that uses string-built filters. The codebase consistently uses .in(field, array) elsewhere. Refactor to:

-  const { data, error } = await supabase
-    .from("in_process_admins")
-    .select("*")
-    .eq("collection", moment.collectionAddress)
-    .or(`token_id.in.(0,${moment.tokenId})`);
+  const { data, error } = await supabase
+    .from("in_process_admins")
+    .select("*")
+    .eq("collection", moment.collectionAddress)
+    .in("token_id", [0, Number(moment.tokenId)]);
+
+  if (error) {
+    console.error("Failed to select admins", error);
+    return [];
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const selectAdmins = async (moment: Moment) => {
const { data, error } = await supabase
.from("in_process_admins")
.select("*")
.eq("collection", moment.collectionAddress)
.or(`token_id.in.(0,${moment.tokenId})`);
if (error) return [];
return data || [];
const selectAdmins = async (moment: Moment) => {
const { data, error } = await supabase
.from("in_process_admins")
.select("*")
.eq("collection", moment.collectionAddress)
.in("token_id", [0, Number(moment.tokenId)]);
if (error) {
console.error("Failed to select admins", error);
return [];
}
return data || [];
};
🤖 Prompt for AI Agents
In lib/supabase/in_process_admins/selectAdmins.ts around lines 4 to 11, the
query uses a string-interpolated .or(`token_id.in.(0,${moment.tokenId})`) which
is inconsistent and less safe than the codebase standard; replace that with the
parameterized .in("token_id", [0, Number(moment.tokenId)]) while keeping the
.eq("collection", moment.collectionAddress) intact so the query becomes
.from("in_process_admins").select("*").eq("collection",
moment.collectionAddress).in("token_id", [0, Number(moment.tokenId)]); ensure
Number() conversion for tokenId and leave the existing error/data handling
unchanged.

) => {
const getMomentOnChainInfo = async (moment: Moment) => {
const { collectionAddress, tokenId, chainId } = moment;
const publicClient: any = getPublicClient(chainId);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Avoid using any type for publicClient.

The PublicClient type is available from viem. Using any bypasses TypeScript's type checking and violates the strict typing guideline.

-  const publicClient: any = getPublicClient(chainId);
+  const publicClient = getPublicClient(chainId);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const publicClient: any = getPublicClient(chainId);
const publicClient = getPublicClient(chainId);
🤖 Prompt for AI Agents
In lib/viem/getTokenInfo.ts around line 16, the variable publicClient is typed
as any which disables TypeScript checks; import the PublicClient type from
'viem' (or the correct export path) and annotate publicClient with that type
(e.g., const publicClient: PublicClient = getPublicClient(chainId)), updating
imports accordingly so the function benefits from strict typing and
autocomplete.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/api/moment/comments/route.ts (1)

45-49: Replace any with unknown for strict type safety.

The catch clause uses e: any, which violates the coding guideline requiring "zero 'any'" types.

As per coding guidelines, use strict TypeScript types. Apply this diff:

-  } catch (e: any) {
+  } catch (e: unknown) {
     console.log(e);
-    const message = e?.message ?? "failed to get comments";
+    const message = e instanceof Error ? e.message : "failed to get comments";
     return Response.json({ message }, { status: 500, headers: corsHeaders });
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29e859a and 8291733.

📒 Files selected for processing (5)
  • app/api/moment/comments/route.ts (1 hunks)
  • lib/moment/fetchComments.ts (1 hunks)
  • lib/moment/getMomentApi.ts (1 hunks)
  • lib/moment/momentComments.ts (2 hunks)
  • lib/schema/commentsSchema.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/moment/fetchComments.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Minimize code to absolute minimum needed - avoid unnecessary abstractions, intermediate steps, or redundant patterns
Write self-documenting code through precise naming (verbs for functions, nouns for variables), single-responsibility components, obvious data flow, and add short comments only when necessary
Apply Single Responsibility Principle (SRP): each function/component should have ONE clear responsibility - extract functions into separate files when they handle distinct concerns - hooks focus on state management, business logic goes in lib files - each function should be in its own file when it has a distinct purpose
Use strict TypeScript types with zero 'any' - prioritize type-exact definitions
Implement built-in security for authentication and data handling - follow secure coding practices throughout the application
Follow Next.js optimization guides for performance - implement proper caching, code splitting, and rendering strategies
Keep all files under 100 lines of code to maintain readability and follow single responsibility principle - split hooks/components when they grow too large or handle multiple concerns
Before coding, make a plan inside a tag: identify core requirement, consider 3 implementation approaches, choose simplest that meets needs, verify if code can be split into smaller functions, check for unnecessary abstractions, and ensure clarity for junior developers

Files:

  • lib/schema/commentsSchema.ts
  • lib/moment/momentComments.ts
  • app/api/moment/comments/route.ts
  • lib/moment/getMomentApi.ts
lib/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Library files should contain pure business logic, data transformation, validation, and API calls - never include React state management or UI concerns

Files:

  • lib/schema/commentsSchema.ts
  • lib/moment/momentComments.ts
  • lib/moment/getMomentApi.ts
🧬 Code graph analysis (3)
lib/schema/commentsSchema.ts (2)
lib/schema/collectSchema.ts (1)
  • momentSchema (5-9)
lib/consts.ts (1)
  • CHAIN_ID (20-20)
app/api/moment/comments/route.ts (1)
lib/consts.ts (1)
  • CHAIN_ID (20-20)
lib/moment/getMomentApi.ts (1)
types/moment.ts (1)
  • Moment (4-8)
🔇 Additional comments (4)
lib/moment/momentComments.ts (1)

3-3: LGTM!

The import change from selectMoments to selectMoment correctly reflects the single-moment fetch pattern.

lib/schema/commentsSchema.ts (1)

3-9: LGTM! Schema updates align with Moment-based model.

The changes correctly:

  • Rename contractAddress to collectionAddress for consistency with the new Moment type
  • Add chainId with a sensible default from CHAIN_ID
  • Match the structure in lib/schema/collectSchema.ts

The schema properly validates the Moment object structure throughout the codebase.

app/api/moment/comments/route.ts (1)

21-28: LGTM! Query parameter construction properly updated.

The changes correctly:

  • Use collectionAddress instead of contractAddress to match the updated schema
  • Parse chainId from search params with appropriate default fallback to CHAIN_ID
  • Construct a moment object that validates against the updated commentsSchema

The validation on line 30 ensures type safety despite the as Address cast.

lib/moment/getMomentApi.ts (1)

10-13: LGTM: Solid error handling.

The error handling correctly manages both HTTP errors and JSON parsing failures with appropriate fallbacks, improving reliability.

Comment on lines +1 to +3
import { Moment } from "@/types/moment";

export const getMomentApi = async (tokenContract: Address, tokenId: string, chainId: number) => {
export const getMomentApi = async (moment: Moment) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add explicit return type annotation.

The function signature lacks an explicit return type, violating the coding guideline: "Use strict TypeScript types with zero 'any' - prioritize type-exact definitions." Without it, the return type is inferred as Promise<any>, allowing any to propagate through the codebase.

As per coding guidelines, define the expected return type structure or import it from your types.

Example:

+import { MomentApiResponse } from "@/types/moment"; // or define inline
+
-export const getMomentApi = async (moment: Moment) => {
+export const getMomentApi = async (moment: Moment): Promise<MomentApiResponse> => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { Moment } from "@/types/moment";
export const getMomentApi = async (tokenContract: Address, tokenId: string, chainId: number) => {
export const getMomentApi = async (moment: Moment) => {
import { MomentApiResponse } from "@/types/moment";
export const getMomentApi = async (moment: Moment): Promise<MomentApiResponse> => {
🤖 Prompt for AI Agents
In lib/moment/getMomentApi.ts lines 1-3, the async function getMomentApi lacks
an explicit return type (currently inferred as Promise<any>), so update the
function signature to declare a precise return type (e.g.,
Promise<YourResponseType>), either by importing an existing response/interface
from your types or by creating a specific type for the API response, and ensure
the implementation conforms to that type so no any is propagated.

Comment on lines +14 to +25
const momentdata = await selectMoment({
collectionAddress: moment.collectionAddress as Address,
tokenId: moment.tokenId,
chainId,
chainId: moment.chainId,
});

const momentData = data[0];

if (!momentData) {
if (!momentdata) {
throw new Error("Moment not found");
}

const comments = await selectComments({
momentId: momentData.id,
momentId: momentdata.id,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Fix variable naming convention and remove type assertion.

Two issues:

  1. Variable momentdata violates camelCase convention—should be momentData.
  2. Type assertion as Address on line 15 bypasses type checking and may hide a type mismatch.

Apply this diff to fix both issues:

-  const momentdata = await selectMoment({
-    collectionAddress: moment.collectionAddress as Address,
+  const momentData = await selectMoment({
+    collectionAddress: moment.collectionAddress,
     tokenId: moment.tokenId,
     chainId: moment.chainId,
   });
 
-  if (!momentdata) {
+  if (!momentData) {
     throw new Error("Moment not found");
   }
 
   const comments = await selectComments({
-    momentId: momentdata.id,
+    momentId: momentData.id,
     offset,
   });

As per coding guidelines, use precise camelCase naming and strict TypeScript types without type assertions.

🤖 Prompt for AI Agents
In lib/moment/momentComments.ts around lines 14 to 25, rename the variable
momentdata to momentData to follow camelCase and remove the unsafe type
assertion "as Address" on moment.collectionAddress; pass collectionAddress:
moment.collectionAddress (rely on correct typing) and if the compiler complains,
update the Moment type or add an explicit runtime validation/conversion for
collectionAddress rather than using a type assertion.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/moment/callUpdateMomentURI.ts (1)

1-39: Fix return type mismatch (Promise<void> vs return data.hash) and tighten error typing to unknown

The function signature declares Promise<void> while the implementation returns data.hash. This is a TypeScript error and must be corrected. Since the caller in hooks/useUpdateMomentURI.ts (line 69) does not capture the return value, and the hash is not used downstream, remove the return data.hash; statement to align with the Promise<void> signature:

export async function callUpdateMomentURI({
  moment,
  newUri,
  accessToken,
}: CallUpdateMomentURIInput): Promise<void> {
  try {
    const response = await fetch("/api/moment/update-uri", {
      method: "POST",
      headers: {
        "content-type": "application/json",
        authorization: `Bearer ${accessToken}`,
      },
      body: JSON.stringify({
        moment,
        newUri,
      }),
    });

    const data = await response.json();
    if (!response.ok) {
      throw new Error(data.message || "Failed to update moment metadata");
    }
-   return data.hash;
  } catch (error: any) {
-   throw new Error(error?.message || "Failed to update moment metadata");
+   if (error instanceof Error) {
+     throw new Error(error.message || "Failed to update moment metadata");
+   }
+   throw new Error("Failed to update moment metadata");
  }
}

Also, replace error: any with error: unknown and add the instanceof Error guard to comply with the zero-any typing standard used throughout the codebase.

🧹 Nitpick comments (2)
lib/moment/updateMomentURI.ts (1)

6-36: Moment-based input looks good; consider whether to use moment.chainId instead of a global chain id

The migration to moment: Moment in UpdateMomentURIInput and the corresponding use of moment.collectionAddress / moment.tokenId in getUpdateTokenURICall is clean and keeps the business logic unchanged. This aligns well with the PR’s move toward a Moment-centric data model.

One thing to double‑check: UpdateMomentURIResult.chainId is still coming from the global CHAIN_ID, and the network for sendUserOperation is derived from IS_TESTNET, while the Moment type itself carries a chainId. If you expect to support multiple chains per deployment, you may eventually want to derive the network/chain id from moment.chainId to avoid drift between the Moment data and the configured constants, even if it’s not required for the current single‑chain setup.

app/api/moment/update-uri/route.ts (1)

7-7: Avoid unchecked as Moment cast by aligning schema typing with the Moment type

Using data.moment as Moment works but is an unsafe cast: it assumes updateMomentURISchema always produces a payload that structurally matches Moment (collectionAddress, tokenId, chainId), without the compiler enforcing that contract. As per coding guidelines, we want strict, exact typing with minimal casts.

If possible, consider typing updateMomentURISchema so that z.infer<typeof updateMomentURISchema> (or the moment field within it) is assignable to Moment, and then pass data.moment directly without as Moment. At minimum, please confirm that the schema and Moment stay in lockstep whenever either changes.

Also applies to: 41-44

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8291733 and 61b6984.

📒 Files selected for processing (4)
  • app/api/moment/update-uri/route.ts (2 hunks)
  • hooks/useUpdateMomentURI.ts (5 hunks)
  • lib/moment/callUpdateMomentURI.ts (3 hunks)
  • lib/moment/updateMomentURI.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • hooks/useUpdateMomentURI.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Minimize code to absolute minimum needed - avoid unnecessary abstractions, intermediate steps, or redundant patterns
Write self-documenting code through precise naming (verbs for functions, nouns for variables), single-responsibility components, obvious data flow, and add short comments only when necessary
Apply Single Responsibility Principle (SRP): each function/component should have ONE clear responsibility - extract functions into separate files when they handle distinct concerns - hooks focus on state management, business logic goes in lib files - each function should be in its own file when it has a distinct purpose
Use strict TypeScript types with zero 'any' - prioritize type-exact definitions
Implement built-in security for authentication and data handling - follow secure coding practices throughout the application
Follow Next.js optimization guides for performance - implement proper caching, code splitting, and rendering strategies
Keep all files under 100 lines of code to maintain readability and follow single responsibility principle - split hooks/components when they grow too large or handle multiple concerns
Before coding, make a plan inside a tag: identify core requirement, consider 3 implementation approaches, choose simplest that meets needs, verify if code can be split into smaller functions, check for unnecessary abstractions, and ensure clarity for junior developers

Files:

  • lib/moment/updateMomentURI.ts
  • app/api/moment/update-uri/route.ts
  • lib/moment/callUpdateMomentURI.ts
lib/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

Library files should contain pure business logic, data transformation, validation, and API calls - never include React state management or UI concerns

Files:

  • lib/moment/updateMomentURI.ts
  • lib/moment/callUpdateMomentURI.ts
🧬 Code graph analysis (3)
lib/moment/updateMomentURI.ts (2)
types/moment.ts (1)
  • Moment (4-8)
lib/coinbase/getOrCreateSmartWallet.ts (1)
  • getOrCreateSmartWallet (6-19)
app/api/moment/update-uri/route.ts (1)
types/moment.ts (1)
  • Moment (4-8)
lib/moment/callUpdateMomentURI.ts (1)
types/moment.ts (1)
  • Moment (4-8)

…o techengme/myc-3542-moment-page-using-new-supabase-table
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant