Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/api/moment/comments/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ export async function GET(req: NextRequest) {
const { searchParams } = new URL(req.url);
const queryParams = {
moment: {
contractAddress: searchParams.get("contractAddress") as Address,
collectionAddress: searchParams.get("collectionAddress") as Address,
tokenId: searchParams.get("tokenId") || "1",
chainId: Number(searchParams.get("chainId")) || CHAIN_ID,
},
chainId: Number(searchParams.get("chainId")) || CHAIN_ID,
offset: Number(searchParams.get("offset")) || 0,
};

Expand Down
63 changes: 17 additions & 46 deletions app/api/moment/route.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { NextRequest, NextResponse } from "next/server";
import { getAddress } from "viem";
import getTokenInfo from "@/lib/viem/getTokenInfo";
import { fetchTokenMetadata } from "@/lib/protocolSdk/ipfs/token-metadata";
import selectAdmins from "@/lib/supabase/in_process_admins/selectAdmins";
import { getMomentAdvancedInfo } from "@/lib/moment/getMomentAdvancedInfo";
import { getAddress } from "viem";
import { getMomentSchema } from "@/lib/schema/getMomentSchema";
import { selectInProcessToken } from "@/lib/supabase/in_process_tokens/selectInProcessToken";
import { CHAIN_ID } from "@/lib/consts";
import { Moment } from "@/types/moment";

export async function GET(req: NextRequest) {
try {
const { searchParams } = new URL(req.url);
const queryParams = {
tokenContract: searchParams.get("tokenContract"),
collectionAddress: searchParams.get("collectionAddress"),
tokenId: searchParams.get("tokenId"),
chainId: searchParams.get("chainId"),
};
Expand All @@ -27,51 +27,22 @@ export async function GET(req: NextRequest) {
);
}

const { tokenContract, tokenId, chainId } = parseResult.data;
const chainIdNum = chainId ? parseInt(chainId, 10) : CHAIN_ID;

// Get token info from chain
const tokenInfo = await getTokenInfo(getAddress(tokenContract), tokenId, chainIdNum);

if (!tokenInfo.tokenUri) {
return NextResponse.json({ error: "Token URI not found" }, { status: 404 });
}

// Fetch metadata from URI
const metadata = await fetchTokenMetadata(tokenInfo.tokenUri);

const token = await selectInProcessToken({
address: getAddress(tokenContract),
chainId: chainIdNum,
});

if (!token) {
return NextResponse.json({ error: "Token not found" }, { status: 404 });
}

// Validate saleConfig exists and has all required fields
if (!tokenInfo.saleConfig) {
return NextResponse.json(
{ error: "Sale configuration not found for this token" },
{ status: 400 }
);
}

const { pricePerToken, saleStart, saleEnd, maxTokensPerAddress } = tokenInfo.saleConfig;

const saleConfig: any = {
...tokenInfo.saleConfig,
pricePerToken: pricePerToken.toString(),
saleStart: Number(saleStart),
saleEnd: Number(saleEnd),
maxTokensPerAddress: Number(maxTokensPerAddress),
const { collectionAddress, tokenId, chainId } = parseResult.data;
const moment: Moment = {
collectionAddress: getAddress(collectionAddress),
tokenId,
chainId: parseInt(chainId, 10),
};
Comment on lines +30 to 35
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.


const { uri, owner, saleConfig } = await getMomentAdvancedInfo(moment);
const metadata = await fetchTokenMetadata(uri || "");
const admins = await selectAdmins(moment);

return NextResponse.json({
uri: tokenInfo.tokenUri,
owner: getAddress(tokenInfo.owner),
uri,
owner,
saleConfig,
momentAdmins: token.token_admins.map((admin) => admin.artist_address),
momentAdmins: admins.map((admin) => admin.artist_address),
metadata: {
name: metadata.name || "",
image: metadata.image || "",
Expand Down
4 changes: 2 additions & 2 deletions app/api/moment/update-uri/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { updateMomentURI } from "@/lib/moment/updateMomentURI";
import { authMiddleware } from "@/middleware/authMiddleware";
import { updateMomentURISchema } from "@/lib/schema/updateMomentURISchema";
import { Address } from "viem";
import { Moment } from "@/types/moment";

// CORS headers for allowing cross-origin requests
const corsHeaders = getCorsHeader();
Expand Down Expand Up @@ -37,8 +38,7 @@ export async function POST(req: NextRequest) {
}
const data = parseResult.data;
const result = await updateMomentURI({
tokenContractAddress: data.moment.contractAddress as Address,
tokenId: data.moment.tokenId,
moment: data.moment as Moment,
newUri: data.newUri,
artistAddress: artistAddress as Address,
});
Expand Down
4 changes: 2 additions & 2 deletions app/api/og/artist/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export async function GET(req: NextRequest) {
let imageMetadata = null;

if (metadata) {
if (metadata.content.mime === "text/plain") {
if (metadata.content?.mime === "text/plain") {
const response = await fetch(getFetchableUrl(metadata.content.uri) || "");
const data = await response.text();
writingText = data;
Expand Down Expand Up @@ -85,7 +85,7 @@ export async function GET(req: NextRequest) {
>
{metadata ? (
<>
{metadata.content.mime === "text/plain" ? (
{metadata.content?.mime === "text/plain" ? (
<TokenWritingPreview writingText={writingText} totalLines={totalLines} />
) : (
<TokenImagePreview imageMetadata={imageMetadata} />
Expand Down
4 changes: 2 additions & 2 deletions app/api/og/token/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export async function GET(req: NextRequest) {
if (!metadata) throw Error("failed to get token metadata");

const previewBackgroundUrl = getFetchableUrl(metadata.image);
const isWriting = metadata.content.mime === "text/plain";
const isWriting = metadata.content?.mime === "text/plain";

let orientation = 1;
let originalWidth = 1;
Expand All @@ -43,7 +43,7 @@ export async function GET(req: NextRequest) {
let writingText = "";

if (isWriting) {
const response = await fetch(getFetchableUrl(metadata.content.uri) || "");
const response = await fetch(getFetchableUrl(metadata.content?.uri) || "");
const data = await response.text();
writingText = data;
const paragraphs = writingText.split("\n");
Expand Down
6 changes: 3 additions & 3 deletions components/ArtSlider/CarouselItem.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { getFetchableUrl } from "@/lib/protocolSdk/ipfs/gateway";
import { Metadata } from "@/types/token";
import { MomentMetadata } from "@/types/moment";
import PdfViewer from "../Renderers/PdfViewer";
import VideoPlayer from "../Renderers/VideoPlayer";
import AudioPlayer from "../Renderers/AudioPlayer";
import Writing from "../Renderers/Writing";

interface CarouselItemProps {
metadata: Metadata;
metadata: MomentMetadata;
}

const CarouselItem = ({ metadata }: CarouselItemProps) => {
Expand Down Expand Up @@ -38,7 +38,7 @@ const CarouselItem = ({ metadata }: CarouselItemProps) => {
return (
<div className="size-full">
<Writing
fileUrl={getFetchableUrl(metadata.content.uri) || ""}
fileUrl={getFetchableUrl(metadata.content?.uri) || ""}
description={metadata.description}
/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/CollectionManagePage/CollectionOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import ContentRenderer from "../Renderers";
import { useCollectionProvider } from "@/providers/CollectionProvider";
import { useRouter } from "next/navigation";
import { Skeleton } from "../ui/skeleton";
import { Metadata } from "@/types/token";
import { MomentMetadata } from "@/types/moment";
import { networkConfigByChain } from "@/lib/protocolSdk/apis/chain-constants";
import CopyButton from "../CopyButton";

Expand Down Expand Up @@ -39,7 +39,7 @@ const CollectionOverview = () => {
{isLoading ? (
<Skeleton className="size-full" />
) : (
<ContentRenderer metadata={data as Metadata} />
<ContentRenderer metadata={data as MomentMetadata} />
)}
</div>
<div className="space-y-2">
Expand Down
4 changes: 2 additions & 2 deletions components/CollectionManagePage/TokenOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { useRouter } from "next/navigation";
import { Skeleton } from "../ui/skeleton";
import { networkConfigByChain } from "@/lib/protocolSdk/apis/chain-constants";
import CopyButton from "../CopyButton";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";
import { useCollectionProvider } from "@/providers/CollectionProvider";

const TokenOverview = () => {
const { metadata, isLoading } = useTokenProvider();
const { metadata, isLoading } = useMomentProvider();
const { push } = useRouter();
const { collection } = useCollectionProvider();

Expand Down
15 changes: 9 additions & 6 deletions components/CreatedMoment/CreatedMomentAirdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@
import { useMomentCreateProvider } from "@/providers/MomentCreateProvider/MomentCreateProvider";
import { Fragment } from "react";
import MomentAirdrop from "../MomentAirdrop";
import { Address } from "viem";
import { TokenProvider } from "@/providers/TokenProvider";
import { MomentProvider } from "@/providers/MomentProvider";
import { CHAIN_ID } from "@/lib/consts";
import { Address } from "viem";

const CreatedMomentAirdrop = () => {
const { createdContract, createdTokenId } = useMomentCreateProvider();

if (!createdContract || !createdTokenId) return <Fragment />;

return (
<TokenProvider
token={{ tokenContractAddress: createdContract as Address, tokenId: createdTokenId }}
chainId={CHAIN_ID}
<MomentProvider
moment={{
collectionAddress: createdContract as Address,
tokenId: createdTokenId,
chainId: CHAIN_ID,
}}
>
<MomentAirdrop />
</TokenProvider>
</MomentProvider>
);
};

Expand Down
4 changes: 2 additions & 2 deletions components/HorizontalFeed/FeedHover.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { FC } from "react";
import { Skeleton } from "../ui/skeleton";
import { Metadata } from "@/types/token";
import { MomentMetadata } from "@/types/moment";
import ContentRenderer from "../Renderers/ContentRenderer";

interface FeedHoverProps {
isLoading: boolean;
data: Metadata;
data: MomentMetadata;
}

const FeedHover: FC<FeedHoverProps> = ({ isLoading, data }) => {
Expand Down
4 changes: 2 additions & 2 deletions components/Renderers/ContentRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { getFetchableUrl } from "@/lib/protocolSdk/ipfs/gateway";
import { usePathname } from "next/navigation";
import { Metadata } from "@/types/token";
import { MomentMetadata } from "@/types/moment";
import PdfViewer from "./PdfViewer";
import VideoPlayer from "./VideoPlayer";
import AudioPlayer from "./AudioPlayer";
import useIsMobile from "@/hooks/useIsMobile";
import Writing from "./Writing";

interface ContentRendererProps {
metadata: Metadata;
metadata: MomentMetadata;
}

const ContentRenderer = ({ metadata }: ContentRendererProps) => {
Expand Down
4 changes: 2 additions & 2 deletions components/TokenManagePage/AirdropButton.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { AirdropItem } from "@/hooks/useAirdrop";
import { useAirdropProvider } from "@/providers/AirdropProvider";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";
import { useUserProvider } from "@/providers/UserProvider";

const AirdropButton = () => {
const { airdopToItems, onAirdrop, loading } = useAirdropProvider();
const { owner, tokenAdmins } = useTokenProvider();
const { owner, tokenAdmins } = useMomentProvider();
const { connectedAddress, artistWallet } = useUserProvider();
const canAirdrop =
Boolean(owner?.toLowerCase() === connectedAddress?.toLowerCase()) ||
Expand Down
4 changes: 2 additions & 2 deletions components/TokenManagePage/AnimationUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import NoFileSelected from "@/components/MetadataCreation/NoFileSelected";
import MediaUploaded from "@/components/MetadataCreation/MediaUploaded";
import ResetButton from "@/components/MetadataCreation/ResetButton";
import useUpdateMomentURI from "@/hooks/useUpdateMomentURI";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";
import { useRef } from "react";
import { useMomentMetadataProvider } from "@/providers/MomentMetadataProvider";
import { useMomentFormProvider } from "@/providers/MomentFormProvider";

const AnimationUpload = () => {
const { isOwner } = useTokenProvider();
const { isOwner } = useMomentProvider();
const { imageUri, animationUri, setImageUri, setAnimationUri } = useMomentFormProvider();
const { fileUpload, fileUploading } = useMomentMetadataProvider();
const { isLoading: isSaving } = useUpdateMomentURI();
Expand Down
4 changes: 2 additions & 2 deletions components/TokenManagePage/Media.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client";

import { Fragment } from "react";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import MediaSkeleton from "./MediaSkeleton";
Expand All @@ -13,7 +13,7 @@ import AnimationUpload from "./AnimationUpload";
import { useMomentFormProvider } from "@/providers/MomentFormProvider";

const Media = () => {
const { metadata, isOwner, isLoading } = useTokenProvider();
const { metadata, isOwner, isLoading } = useMomentProvider();
const { form } = useMomentFormProvider();
const { isLoading: isSaving } = useUpdateMomentURI();

Expand Down
4 changes: 2 additions & 2 deletions components/TokenManagePage/OwnerWarning.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use client";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";

const OwnerWarning = () => {
const { isOwner } = useTokenProvider();
const { isOwner } = useMomentProvider();

if (isOwner) return null;

Expand Down
4 changes: 2 additions & 2 deletions components/TokenManagePage/Sale.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import useSaleConfig from "@/hooks/useSaleConfig";
import { Fragment } from "react";
import { DateTimePicker } from "../ui/date-time-picker";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";

const Sale = () => {
const { saleStart, setSaleStart, setSale, isLoading } = useSaleConfig();
const { saleConfig } = useTokenProvider();
const { saleConfig } = useMomentProvider();

if (!saleConfig) return <Fragment />;
return (
Expand Down
4 changes: 2 additions & 2 deletions components/TokenManagePage/SaveMediaButton.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"use client";
import { useTokenProvider } from "@/providers/TokenProvider";
import { useMomentProvider } from "@/providers/MomentProvider";
import useUpdateMomentURI from "@/hooks/useUpdateMomentURI";
import { toast } from "sonner";
import { useFormState } from "react-hook-form";
import { useMomentFormProvider } from "@/providers/MomentFormProvider";

const SaveMediaButton = () => {
const { isOwner } = useTokenProvider();
const { isOwner } = useMomentProvider();
const { updateTokenURI, isLoading: isSaving } = useUpdateMomentURI();
const { form } = useMomentFormProvider();
const { errors } = useFormState({ control: form.control });
Expand Down
12 changes: 6 additions & 6 deletions components/TokenManagePage/TokenManagePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import ManageTabs, { MANAGE_TABS } from "./ManageTabs";
import Sale from "./Sale";
import Media from "./Media";
import { useParams } from "next/navigation";
import { TokenProvider } from "@/providers/TokenProvider";
import { MomentProvider } from "@/providers/MomentProvider";
import { useCollectionProvider } from "@/providers/CollectionProvider";
import TokenOverview from "../CollectionManagePage/TokenOverview";
import MomentAirdrop from "../MomentAirdrop";
Expand All @@ -17,12 +17,12 @@ const TokenManagePage = () => {
const tokenId = params.tokenId as string;

return (
<TokenProvider
token={{
tokenContractAddress: collection.address,
<MomentProvider
moment={{
collectionAddress: collection.address,
tokenId,
chainId: collection.chainId,
}}
chainId={collection.chainId}
>
<TokenOverview />
<ManageTabs
Expand All @@ -34,7 +34,7 @@ const TokenManagePage = () => {
{selectedTab === MANAGE_TABS.SALE && <Sale />}
{selectedTab === MANAGE_TABS.MEDIA && <Media />}
</div>
</TokenProvider>
</MomentProvider>
);
};

Expand Down
Loading