From afb775bc6781a2567a901e8c1681e168b670950d Mon Sep 17 00:00:00 2001 From: gm3 Date: Sat, 29 Nov 2025 00:22:49 +1000 Subject: [PATCH 1/3] update apis --- app/api/moment/update-uri/route.ts | 7 +++++-- .../CreatedMoment/CreatedMomentAirdrop.tsx | 7 +++++-- .../TokenManagePage/TokenManagePage.tsx | 6 +++--- components/TokenPage/TokenPage.tsx | 6 +++--- hooks/useAirdrop.ts | 7 +++---- hooks/useBalanceOf.ts | 10 +++++----- hooks/useComments.ts | 4 ++-- hooks/useMomentCollect.ts | 16 ++++----------- hooks/useSaleConfig.ts | 15 ++++++++------ hooks/useShareMoment.ts | 4 ++-- hooks/useTokenInfo.ts | 9 +++++---- hooks/useUpdateMomentURI.ts | 17 +++++++++------- lib/moment/airdropMoment.ts | 8 ++++---- lib/moment/callUpdateMomentURI.ts | 13 +++++------- lib/moment/collectMoment.ts | 11 ++++------ lib/moment/collectMomentApi.ts | 5 +---- lib/moment/executeAirdrop.ts | 15 +++++++------- lib/moment/fetchComments.ts | 2 +- lib/moment/getMomentApi.ts | 10 +++++----- lib/moment/updateMomentURI.ts | 13 +++++++----- lib/schema/airdropMomentSchema.ts | 2 +- lib/schema/collectSchema.ts | 4 +++- providers/MomentProvider.tsx | 20 ++++++------------- types/moment.ts | 4 ++-- types/token.ts | 6 ------ 25 files changed, 103 insertions(+), 118 deletions(-) diff --git a/app/api/moment/update-uri/route.ts b/app/api/moment/update-uri/route.ts index b95b6a79..42f4637d 100644 --- a/app/api/moment/update-uri/route.ts +++ b/app/api/moment/update-uri/route.ts @@ -37,8 +37,11 @@ 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: { + collectionAddress: data.moment.collectionAddress as Address, + tokenId: data.moment.tokenId, + chainId: data.moment.chainId, + }, newUri: data.newUri, artistAddress: artistAddress as Address, }); diff --git a/components/CreatedMoment/CreatedMomentAirdrop.tsx b/components/CreatedMoment/CreatedMomentAirdrop.tsx index 241d389e..b5f5bf9e 100644 --- a/components/CreatedMoment/CreatedMomentAirdrop.tsx +++ b/components/CreatedMoment/CreatedMomentAirdrop.tsx @@ -14,8 +14,11 @@ const CreatedMomentAirdrop = () => { return ( diff --git a/components/TokenManagePage/TokenManagePage.tsx b/components/TokenManagePage/TokenManagePage.tsx index 6042a28a..f2170dc5 100644 --- a/components/TokenManagePage/TokenManagePage.tsx +++ b/components/TokenManagePage/TokenManagePage.tsx @@ -18,11 +18,11 @@ const TokenManagePage = () => { return ( { const viemChainName = ZORA_TO_VIEM[chain as ZoraChains]; const viemChain = chains[viemChainName]; - const token = { - tokenContractAddress: address as Address, + const moment = { + collectionAddress: address as Address, tokenId, chainId: viemChain.id, }; @@ -27,7 +27,7 @@ const TokenPage = () => { return (
- + diff --git a/hooks/useAirdrop.ts b/hooks/useAirdrop.ts index d54a8917..38d558f4 100644 --- a/hooks/useAirdrop.ts +++ b/hooks/useAirdrop.ts @@ -16,8 +16,8 @@ export interface AirdropItem { ensName: string; } const useAirdrop = () => { - const { token } = useMomentProvider(); - const { tokenContractAddress: momentContract, tokenId } = token; + const { moment } = useMomentProvider(); + const { collectionAddress, tokenId } = moment; const [airdopToItems, setAirdropToItems] = useState([]); const { artistWallet, isPrepared } = useUserProvider(); const { smartWallet } = useSmartWalletProvider(); @@ -66,8 +66,7 @@ const useAirdrop = () => { const hash = await executeAirdrop({ airdropToItems: airdopToItems, - tokenId, - momentContract, + moment, smartWallet: smartWallet as Address, artistWallet: artistWallet as Address, accessToken, diff --git a/hooks/useBalanceOf.ts b/hooks/useBalanceOf.ts index cf88be03..be403c9f 100644 --- a/hooks/useBalanceOf.ts +++ b/hooks/useBalanceOf.ts @@ -7,23 +7,23 @@ import { Address } from "viem"; const useBalanceOf = () => { const [balanceOf, setBalanceOf] = useState(0); - const { token } = useMomentProvider(); + const { moment } = useMomentProvider(); const { connectedAddress } = useUserProvider(); useEffect(() => { const getBalanceOf = async () => { const publicClient = getPublicClient(); const response = await publicClient.readContract({ - address: token.tokenContractAddress as Address, + address: moment.collectionAddress as Address, abi: zoraCreator1155ImplABI, functionName: "balanceOf", - args: [connectedAddress as Address, BigInt(token.tokenId)], + args: [connectedAddress as Address, BigInt(moment.tokenId)], }); setBalanceOf(parseInt(response.toString(), 10)); }; - if (token && connectedAddress) getBalanceOf(); - }, [token, connectedAddress]); + if (moment && connectedAddress) getBalanceOf(); + }, [moment, connectedAddress]); return { balanceOf, diff --git a/hooks/useComments.ts b/hooks/useComments.ts index 95442d97..abbb9ab7 100644 --- a/hooks/useComments.ts +++ b/hooks/useComments.ts @@ -8,9 +8,9 @@ import { useMomentProvider } from "@/providers/MomentProvider"; const COMMENTS_PER_PAGE = 20; export function useComments() { - const { token } = useMomentProvider(); + const { moment } = useMomentProvider(); const queryClient = useQueryClient(); - const { tokenContractAddress: contractAddress, tokenId, chainId } = token; + const { collectionAddress: contractAddress, tokenId, chainId } = moment; const query = useInfiniteQuery({ queryKey: ["comments", contractAddress, tokenId, chainId], diff --git a/hooks/useMomentCollect.ts b/hooks/useMomentCollect.ts index 5be0263b..3c167908 100644 --- a/hooks/useMomentCollect.ts +++ b/hooks/useMomentCollect.ts @@ -33,7 +33,7 @@ const useMomentCollect = () => { const [collected, setCollected] = useState(false); const { artistWallet } = useUserProvider(); const [isLoading, setIsLoading] = useState(false); - const { token, saleConfig } = useMomentProvider(); + const { moment, saleConfig } = useMomentProvider(); const { comment, addComment, setComment, setIsOpenCommentModal } = useMomentCommentsProvider(); const { validateBalance } = useCollectBalanceValidation(); const { getAccessToken } = usePrivy(); @@ -50,12 +50,12 @@ const useMomentCollect = () => { if (saleConfig.pricePerToken === BigInt(0)) { await mintOnSmartWallet({ - address: token.tokenContractAddress, + address: moment.collectionAddress, abi: zoraCreator1155ImplABI, functionName: "mint", args: [ zoraCreatorFixedPriceSaleStrategyAddress[CHAIN.id], - token.tokenId, + moment.tokenId, amountToCollect, [], minterArguments, @@ -67,15 +67,7 @@ const useMomentCollect = () => { if (!accessToken) { throw new Error("Failed to get access token"); } - await collectMomentApi( - { - contractAddress: token.tokenContractAddress, - tokenId: token.tokenId, - }, - amountToCollect, - comment, - accessToken - ); + await collectMomentApi(moment, amountToCollect, comment, accessToken); } addComment({ sender: artistWallet as Address, diff --git a/hooks/useSaleConfig.ts b/hooks/useSaleConfig.ts index 61dc3ee9..839e0cde 100644 --- a/hooks/useSaleConfig.ts +++ b/hooks/useSaleConfig.ts @@ -12,9 +12,8 @@ import { zoraCreatorFixedPriceSaleStrategyAddress } from "@/lib/protocolSdk/cons import { useUserProvider } from "@/providers/UserProvider"; const useSaleConfig = () => { - const { saleConfig: sale } = useMomentProvider(); + const { saleConfig: sale, moment, fetchTokenInfo } = useMomentProvider(); const [saleStart, setSaleStart] = useState(new Date()); - const { token, fetchTokenInfo } = useMomentProvider(); const { signTransaction } = useSignTransaction(); const { connectedAddress } = useUserProvider(); const [isLoading, setIsLoading] = useState(false); @@ -29,14 +28,18 @@ const useSaleConfig = () => { const calldata = encodeFunctionData({ abi: zoraCreatorFixedPriceSaleStrategyABI, functionName: "setSale", - args: [BigInt(token.tokenId), newSale], + args: [BigInt(moment.tokenId), newSale], }); - const publicClient = getPublicClient(CHAIN_ID); + const publicClient = getPublicClient(moment.chainId || 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[moment.chainId || CHAIN_ID], + calldata, + ], account: connectedAddress as Address, chain: CHAIN, }); diff --git a/hooks/useShareMoment.ts b/hooks/useShareMoment.ts index 9bd2bd32..ab8f47b9 100644 --- a/hooks/useShareMoment.ts +++ b/hooks/useShareMoment.ts @@ -4,12 +4,12 @@ import { useMomentProvider } from "@/providers/MomentProvider"; import { toast } from "sonner"; const useShareMoment = () => { - const { token } = useMomentProvider(); + const { moment } = useMomentProvider(); const share = async () => { const shortNetworkName = getShortNetworkName(CHAIN.name.toLowerCase()); await navigator.clipboard.writeText( - `${SITE_ORIGINAL_URL}/collect/${shortNetworkName}:${token.tokenContractAddress}/${token.tokenId}` + `${SITE_ORIGINAL_URL}/collect/${shortNetworkName}:${moment.collectionAddress}/${moment.tokenId}` ); toast.success("copied!"); }; diff --git a/hooks/useTokenInfo.ts b/hooks/useTokenInfo.ts index 5025e0cf..2f0a844b 100644 --- a/hooks/useTokenInfo.ts +++ b/hooks/useTokenInfo.ts @@ -3,14 +3,15 @@ import { useMemo } from "react"; import { useQuery } from "@tanstack/react-query"; import { useUserProvider } from "@/providers/UserProvider"; import { getMomentApi } from "@/lib/moment/getMomentApi"; +import { Moment } from "@/types/moment"; -const useTokenInfo = (tokenContract: Address, tokenId: string, chainId: number) => { +const useTokenInfo = (moment: Moment) => { const { artistWallet } = useUserProvider(); const query = useQuery({ - queryKey: ["tokenInfo", tokenContract, tokenId, chainId], - queryFn: () => getMomentApi(tokenContract, tokenId, chainId), - enabled: Boolean(tokenContract && tokenId && chainId), + queryKey: ["tokenInfo", moment.collectionAddress, moment.tokenId, moment.chainId], + queryFn: () => getMomentApi(moment), + enabled: Boolean(moment.collectionAddress && moment.tokenId), staleTime: 1000 * 60 * 5, // 5 minutes retry: (failureCount) => failureCount < 3, }); diff --git a/hooks/useUpdateMomentURI.ts b/hooks/useUpdateMomentURI.ts index 18d5ac0b..3148439c 100644 --- a/hooks/useUpdateMomentURI.ts +++ b/hooks/useUpdateMomentURI.ts @@ -11,7 +11,7 @@ import { useMomentFormProvider } from "@/providers/MomentFormProvider"; import { migrateMuxToArweaveApi } from "@/lib/mux/migrateMuxToArweaveApi"; const useUpdateMomentURI = () => { - const { token, fetchTokenInfo } = useMomentProvider(); + const { moment, fetchTokenInfo } = useMomentProvider(); const { name: providerName, description: providerDescription, @@ -27,7 +27,11 @@ const useUpdateMomentURI = () => { const updateTokenURI = async () => { setIsLoading(true); try { - const tokenInfo = await getTokenInfo(token.tokenContractAddress, token.tokenId, CHAIN_ID); + const tokenInfo = await getTokenInfo( + moment.collectionAddress, + moment.tokenId, + moment.chainId || CHAIN_ID + ); const current = await fetchTokenMetadata(tokenInfo.tokenUri); const updatedAnimationUrl = animationUri || current?.animation_url; @@ -56,7 +60,7 @@ const useUpdateMomentURI = () => { const newUri = await uploadJson(updated); - if (!token?.tokenContractAddress || !token?.tokenId) { + if (!moment?.collectionAddress || !moment?.tokenId) { throw new Error("Missing token context"); } @@ -66,16 +70,15 @@ const useUpdateMomentURI = () => { } await callUpdateMomentURI({ - tokenContractAddress: token.tokenContractAddress, - tokenId: token.tokenId, + moment, newUri, accessToken, }); if (updatedMimeType?.includes("video")) { await migrateMuxToArweaveApi({ - tokenContractAddress: token.tokenContractAddress, - tokenId: token.tokenId, + tokenContractAddress: moment.collectionAddress, + tokenId: moment.tokenId, accessToken, }); resetForm(); diff --git a/lib/moment/airdropMoment.ts b/lib/moment/airdropMoment.ts index 40a73db5..78fefc92 100644 --- a/lib/moment/airdropMoment.ts +++ b/lib/moment/airdropMoment.ts @@ -22,7 +22,7 @@ export interface AirdropResult { */ export async function airdropMoment({ recipients, - momentContract, + collectionAddress, artistAddress, }: AirdropMomentInput): Promise { // Get or create a smart account (contract wallet) @@ -32,12 +32,12 @@ export async function airdropMoment({ // Check admin permission of artist wallet and smart wallet const smartWalletPermissionBit = await getPermission( - momentContract as Address, + collectionAddress as Address, smartAccount.address ); if (smartWalletPermissionBit !== BigInt(PERMISSION_BIT_ADMIN)) { - const accountPermissionBit = await getPermission(momentContract as Address, artistAddress); + const accountPermissionBit = await getPermission(collectionAddress as Address, artistAddress); if (accountPermissionBit !== BigInt(PERMISSION_BIT_ADMIN)) throw Error("The account does not have admin permission for this collection."); else throw Error("Admin permission are not yet granted to smart wallet."); @@ -64,7 +64,7 @@ export async function airdropMoment({ network: IS_TESTNET ? "base-sepolia" : "base", calls: [ { - to: momentContract as Address, + to: collectionAddress as Address, data: airdropCall, }, ], diff --git a/lib/moment/callUpdateMomentURI.ts b/lib/moment/callUpdateMomentURI.ts index 7eb236eb..56ac5399 100644 --- a/lib/moment/callUpdateMomentURI.ts +++ b/lib/moment/callUpdateMomentURI.ts @@ -1,6 +1,7 @@ +import { Moment } from "@/types/moment"; + export interface CallUpdateMomentURIInput { - tokenContractAddress: string; - tokenId: string; + moment: Moment; newUri: string; accessToken: string; } @@ -10,8 +11,7 @@ export interface CallUpdateMomentURIInput { * Handles authentication and error responses. */ export async function callUpdateMomentURI({ - tokenContractAddress, - tokenId, + moment, newUri, accessToken, }: CallUpdateMomentURIInput): Promise { @@ -23,10 +23,7 @@ export async function callUpdateMomentURI({ authorization: `Bearer ${accessToken}`, }, body: JSON.stringify({ - moment: { - contractAddress: tokenContractAddress, - tokenId: tokenId, - }, + moment, newUri, }), }); diff --git a/lib/moment/collectMoment.ts b/lib/moment/collectMoment.ts index 1240a7a9..6ce2921a 100644 --- a/lib/moment/collectMoment.ts +++ b/lib/moment/collectMoment.ts @@ -29,24 +29,21 @@ export async function collectMoment({ amount, artistAddress, }: CollectMomentInput): Promise { + const { collectionAddress, tokenId } = moment; // Get or create a smart account (contract wallet) const smartAccount = await getOrCreateSmartWallet({ address: artistAddress, }); // Get token info and sale config - const { saleConfig } = await getTokenInfo( - moment.contractAddress as Address, - moment.tokenId, - CHAIN_ID - ); + const { saleConfig } = await getTokenInfo(collectionAddress as Address, tokenId, CHAIN_ID); const approveCall = await validateBalanceAndAllowance(smartAccount.address, saleConfig, amount); // Get the collect call using the shared function const collectCall = getCollectCall( - moment.contractAddress as Address, - Number(moment.tokenId), + collectionAddress as Address, + Number(tokenId), saleConfig, artistAddress, comment, diff --git a/lib/moment/collectMomentApi.ts b/lib/moment/collectMomentApi.ts index 8008357d..d7bc2a7c 100644 --- a/lib/moment/collectMomentApi.ts +++ b/lib/moment/collectMomentApi.ts @@ -14,10 +14,7 @@ export const collectMomentApi = async ( Authorization: `Bearer ${accessToken}`, }, body: JSON.stringify({ - moment: { - contractAddress: moment.contractAddress, - tokenId: moment.tokenId, - }, + moment, amount, comment, }), diff --git a/lib/moment/executeAirdrop.ts b/lib/moment/executeAirdrop.ts index 254ca714..fb312098 100644 --- a/lib/moment/executeAirdrop.ts +++ b/lib/moment/executeAirdrop.ts @@ -1,4 +1,5 @@ import { Address } from "viem"; +import { Moment } from "@/types/moment"; import getPermission from "@/lib/zora/getPermission"; import { PERMISSION_BIT_ADMIN } from "@/lib/consts"; @@ -9,8 +10,7 @@ export interface AirdropRecipient { export interface ExecuteAirdropParams { airdropToItems: Array<{ address: string }>; - tokenId: string; - momentContract: Address; + moment: Moment; smartWallet: Address; artistWallet: Address; accessToken: string; @@ -18,8 +18,7 @@ export interface ExecuteAirdropParams { export const executeAirdrop = async ({ airdropToItems, - tokenId, - momentContract, + moment, smartWallet, artistWallet, accessToken, @@ -27,14 +26,14 @@ export const executeAirdrop = async ({ // Create recipients array from airdropToItems const recipients = Array.from({ length: airdropToItems.length }).map((_, i) => ({ recipientAddress: airdropToItems[i].address, - tokenId: tokenId, + tokenId: moment.tokenId, })); // Check smart wallet permissions - const smartWalletPermission = await getPermission(momentContract, smartWallet); + const smartWalletPermission = await getPermission(moment.collectionAddress, smartWallet); if (smartWalletPermission !== BigInt(PERMISSION_BIT_ADMIN)) { // Check artist wallet permissions as fallback - const artistWalletPermission = await getPermission(momentContract, artistWallet); + const artistWalletPermission = await getPermission(moment.collectionAddress, artistWallet); if (artistWalletPermission !== BigInt(PERMISSION_BIT_ADMIN)) { throw new Error("The account does not have admin permission for this collection."); @@ -48,7 +47,7 @@ export const executeAirdrop = async ({ method: "POST", body: JSON.stringify({ recipients, - momentContract, + collectionAddress: moment.collectionAddress, }), headers: { "content-type": "application/json", diff --git a/lib/moment/fetchComments.ts b/lib/moment/fetchComments.ts index 1cb1bfe1..eeb97de3 100644 --- a/lib/moment/fetchComments.ts +++ b/lib/moment/fetchComments.ts @@ -12,7 +12,7 @@ async function fetchComments({ }: MomentCommentsInput): Promise { try { const params: CommentsQueryParams = { - contractAddress: moment.contractAddress, + contractAddress: moment.collectionAddress, tokenId: moment.tokenId, chainId, offset, diff --git a/lib/moment/getMomentApi.ts b/lib/moment/getMomentApi.ts index 66ccc1ac..94267bbc 100644 --- a/lib/moment/getMomentApi.ts +++ b/lib/moment/getMomentApi.ts @@ -1,10 +1,10 @@ -import { Address } from "viem"; +import { Moment } from "@/types/moment"; -export const getMomentApi = async (tokenContract: Address, tokenId: string, chainId: number) => { +export const getMomentApi = async (moment: Moment) => { const params = new URLSearchParams({ - tokenContract, - tokenId, - chainId: String(chainId), + tokenContract: moment.collectionAddress, + tokenId: moment.tokenId, + ...(moment.chainId && { chainId: String(moment.chainId) }), }); const res = await fetch(`/api/moment?${params.toString()}`); if (!res.ok) { diff --git a/lib/moment/updateMomentURI.ts b/lib/moment/updateMomentURI.ts index 1a974198..ccb53b38 100644 --- a/lib/moment/updateMomentURI.ts +++ b/lib/moment/updateMomentURI.ts @@ -3,10 +3,10 @@ import { CHAIN_ID, IS_TESTNET } from "@/lib/consts"; import { sendUserOperation } from "@/lib/coinbase/sendUserOperation"; import getUpdateTokenURICall from "@/lib/viem/getUpdateTokenURICall"; import { getOrCreateSmartWallet } from "@/lib/coinbase/getOrCreateSmartWallet"; +import { Moment } from "@/types/moment"; export interface UpdateMomentURIInput { - tokenContractAddress: Address; - tokenId: string; + moment: Moment; newUri: string; artistAddress: Address; } @@ -21,8 +21,7 @@ export interface UpdateMomentURIResult { * Handles the transaction on the backend side. */ export async function updateMomentURI({ - tokenContractAddress, - tokenId, + moment, newUri, artistAddress, }: UpdateMomentURIInput): Promise { @@ -30,7 +29,11 @@ export async function updateMomentURI({ address: artistAddress, }); - const updateTokenURICall = getUpdateTokenURICall(tokenContractAddress, tokenId, newUri); + const updateTokenURICall = getUpdateTokenURICall( + moment.collectionAddress, + moment.tokenId, + newUri + ); // Send the transaction and wait for receipt using the helper const transaction = await sendUserOperation({ diff --git a/lib/schema/airdropMomentSchema.ts b/lib/schema/airdropMomentSchema.ts index e36f26de..d9a7a048 100644 --- a/lib/schema/airdropMomentSchema.ts +++ b/lib/schema/airdropMomentSchema.ts @@ -11,5 +11,5 @@ export const recipientsSchema = z.array( export const airdropMomentSchema = z.object({ recipients: recipientsSchema, - momentContract: addressSchema, + collectionAddress: addressSchema, }); diff --git a/lib/schema/collectSchema.ts b/lib/schema/collectSchema.ts index d2c8e1d0..b189b801 100644 --- a/lib/schema/collectSchema.ts +++ b/lib/schema/collectSchema.ts @@ -1,9 +1,11 @@ import { z } from "zod"; import addressSchema from "./addressSchema"; +import { CHAIN_ID } from "../consts"; export const momentSchema = z.object({ tokenId: z.string(), - contractAddress: addressSchema, + collectionAddress: addressSchema, + chainId: z.number().optional().default(CHAIN_ID), }); export const collectSchema = z.object({ diff --git a/providers/MomentProvider.tsx b/providers/MomentProvider.tsx index 84749f4c..c577ac0c 100644 --- a/providers/MomentProvider.tsx +++ b/providers/MomentProvider.tsx @@ -1,31 +1,23 @@ import useTokenInfo from "@/hooks/useTokenInfo"; -import { TokenInfo } from "@/types/token"; +import { Moment } from "@/types/moment"; import { createContext, useContext, ReactNode } from "react"; // eslint-disable-next-line @typescript-eslint/no-explicit-any const MomentContext = createContext< | (ReturnType & { - token: TokenInfo; + moment: Moment; }) | undefined >(undefined); -export function MomentProvider({ - children, - token, - chainId, -}: { - children: ReactNode; - token: TokenInfo; - chainId: number; -}) { - const tokenInfo = useTokenInfo(token.tokenContractAddress, token.tokenId, chainId); +export function MomentProvider({ children, moment }: { children: ReactNode; moment: Moment }) { + const momentdata = useTokenInfo(moment); return ( {children} diff --git a/types/moment.ts b/types/moment.ts index bbe0d745..0f6e1b92 100644 --- a/types/moment.ts +++ b/types/moment.ts @@ -2,13 +2,13 @@ import { Address } from "viem"; import type { Database } from "@/lib/supabase/types"; export interface Moment { - contractAddress: Address; + collectionAddress: Address; tokenId: string; + chainId?: number; } export interface MomentCommentsInput { moment: Moment; - chainId: number; offset: number; } diff --git a/types/token.ts b/types/token.ts index e4bd75cb..f6240590 100644 --- a/types/token.ts +++ b/types/token.ts @@ -11,12 +11,6 @@ export interface TokenMetadata { canvas_url?: string; } -export interface TokenInfo { - tokenId: string; - tokenContractAddress: Address; - chainId?: number; -} - export interface Metadata { image: string; name: string; From 6105949c98823953cc77d0e065392ab74691df91 Mon Sep 17 00:00:00 2001 From: gm3 Date: Sat, 29 Nov 2025 00:51:47 +1000 Subject: [PATCH 2/3] fix moment type --- app/api/moment/comments/route.ts | 2 +- hooks/useComments.ts | 6 +----- hooks/useSaleConfig.ts | 4 +++- lib/moment/fetchComments.ts | 13 +++++-------- lib/moment/momentComments.ts | 5 ++--- lib/schema/commentsSchema.ts | 4 +++- lib/supabase/in_process_moments/selectMoments.ts | 13 +++---------- 7 files changed, 18 insertions(+), 29 deletions(-) diff --git a/app/api/moment/comments/route.ts b/app/api/moment/comments/route.ts index 0cec5f55..5f4555d1 100644 --- a/app/api/moment/comments/route.ts +++ b/app/api/moment/comments/route.ts @@ -20,7 +20,7 @@ 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, diff --git a/hooks/useComments.ts b/hooks/useComments.ts index abbb9ab7..41c57894 100644 --- a/hooks/useComments.ts +++ b/hooks/useComments.ts @@ -16,11 +16,7 @@ export function useComments() { queryKey: ["comments", contractAddress, tokenId, chainId], queryFn: ({ pageParam = 0 }) => fetchComments({ - moment: { - contractAddress: contractAddress!, - tokenId: tokenId!, - }, - chainId: chainId!, + moment, offset: pageParam as number, }), enabled: Boolean(contractAddress && tokenId && chainId), diff --git a/hooks/useSaleConfig.ts b/hooks/useSaleConfig.ts index 839e0cde..11c61f64 100644 --- a/hooks/useSaleConfig.ts +++ b/hooks/useSaleConfig.ts @@ -37,7 +37,9 @@ const useSaleConfig = () => { functionName: "callSale", args: [ moment.tokenId, - zoraCreatorFixedPriceSaleStrategyAddress[moment.chainId || CHAIN_ID], + zoraCreatorFixedPriceSaleStrategyAddress[ + moment.chainId as keyof typeof zoraCreatorFixedPriceSaleStrategyAddress + ], calldata, ], account: connectedAddress as Address, diff --git a/lib/moment/fetchComments.ts b/lib/moment/fetchComments.ts index eeb97de3..b5d58336 100644 --- a/lib/moment/fetchComments.ts +++ b/lib/moment/fetchComments.ts @@ -4,23 +4,20 @@ import { MomentCommentsInput, MomentCommentsResult, } from "@/types/moment"; +import { base } from "viem/chains"; -async function fetchComments({ - moment, - chainId, - offset, -}: MomentCommentsInput): Promise { +async function fetchComments({ moment, offset }: MomentCommentsInput): Promise { try { const params: CommentsQueryParams = { contractAddress: moment.collectionAddress, tokenId: moment.tokenId, - chainId, + chainId: moment.chainId ?? base.id, // Default to Base mainnet offset, }; const queryString = new URLSearchParams({ - contractAddress: params.contractAddress, - tokenId: params.tokenId, + collectionAddress: moment.collectionAddress, + tokenId: moment.tokenId, chainId: params.chainId.toString(), offset: params.offset?.toString() || "0", }); diff --git a/lib/moment/momentComments.ts b/lib/moment/momentComments.ts index d7cc4092..1161964b 100644 --- a/lib/moment/momentComments.ts +++ b/lib/moment/momentComments.ts @@ -9,13 +9,12 @@ export type GetCommentsInput = z.infer; export async function momentComments({ moment, - chainId, offset, }: GetCommentsInput): Promise { const data = await selectMoments({ - collectionAddress: moment.contractAddress as Address, + collectionAddress: moment.collectionAddress as Address, tokenId: moment.tokenId, - chainId, + chainId: moment.chainId, }); const momentData = data[0]; diff --git a/lib/schema/commentsSchema.ts b/lib/schema/commentsSchema.ts index 89abf761..21fac0f5 100644 --- a/lib/schema/commentsSchema.ts +++ b/lib/schema/commentsSchema.ts @@ -1,9 +1,11 @@ import { z } from "zod"; import addressSchema from "./addressSchema"; +import { CHAIN_ID } from "../consts"; export const momentSchema = z.object({ tokenId: z.string(), - contractAddress: addressSchema, + collectionAddress: addressSchema, + chainId: z.number().optional().default(CHAIN_ID), }); export const commentsSchema = z.object({ diff --git a/lib/supabase/in_process_moments/selectMoments.ts b/lib/supabase/in_process_moments/selectMoments.ts index 288be188..418be5c7 100644 --- a/lib/supabase/in_process_moments/selectMoments.ts +++ b/lib/supabase/in_process_moments/selectMoments.ts @@ -1,15 +1,8 @@ -import { Address } from "viem"; import { supabase } from "../client"; +import { Moment } from "@/types/moment"; -const selectMoments = async ({ - collectionAddress, - tokenId, - chainId, -}: { - collectionAddress: Address; - tokenId: string; - chainId: number; -}) => { +const selectMoments = async (moment: Moment) => { + const { collectionAddress, chainId, tokenId } = moment; let query = supabase .from("in_process_moments") .select("*, collection:in_process_collections!inner(*)"); From fcb2f73acf87d943626e5a96d371befbf0bbe1b6 Mon Sep 17 00:00:00 2001 From: gm3 Date: Sat, 29 Nov 2025 01:02:25 +1000 Subject: [PATCH 3/3] fix feedback --- hooks/useComments.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hooks/useComments.ts b/hooks/useComments.ts index 41c57894..ea7098b9 100644 --- a/hooks/useComments.ts +++ b/hooks/useComments.ts @@ -10,16 +10,16 @@ const COMMENTS_PER_PAGE = 20; export function useComments() { const { moment } = useMomentProvider(); const queryClient = useQueryClient(); - const { collectionAddress: contractAddress, tokenId, chainId } = moment; + const { collectionAddress, tokenId, chainId } = moment; const query = useInfiniteQuery({ - queryKey: ["comments", contractAddress, tokenId, chainId], + queryKey: ["comments", collectionAddress, tokenId, chainId], queryFn: ({ pageParam = 0 }) => fetchComments({ moment, offset: pageParam as number, }), - enabled: Boolean(contractAddress && tokenId && chainId), + enabled: Boolean(moment), staleTime: 1000 * 60 * 5, // 5 minutes retry: (failureCount) => failureCount < 3, getNextPageParam: (lastPage, allPages) => { @@ -44,7 +44,7 @@ export function useComments() { (comment: MintComment) => { // Optimistically update the query cache queryClient.setQueryData>( - ["comments", contractAddress, tokenId, chainId], + ["comments", collectionAddress, tokenId, chainId], (oldData) => { if (!oldData) { return { @@ -60,7 +60,7 @@ export function useComments() { } ); }, - [queryClient, contractAddress, tokenId, chainId] + [queryClient, collectionAddress, tokenId, chainId] ); const fetchMore = useCallback(() => {