diff --git a/packages/foundry/contracts/PunkSociety.sol b/packages/foundry/contracts/PunkSociety.sol index 91cb804..f023292 100644 --- a/packages/foundry/contracts/PunkSociety.sol +++ b/packages/foundry/contracts/PunkSociety.sol @@ -119,7 +119,9 @@ contract PunkSociety is Ownable { postIdToUser[postId] = msg.sender; userPosts[msg.sender].push(postId); - mockUSDC.transferFrom(msg.sender, owner(), 3 * 1e6); + bool sent = mockUSDC.transferFrom(msg.sender, owner(), 3 * 1e6); + require(sent, "Failed to send USDC to the post owner"); + punkPosts.mint(_tokenURI); // payable(owner()).transfer(3 ether); @@ -148,13 +150,15 @@ contract PunkSociety is Ownable { address postOwner = postIdToUser[_postID]; require(postOwner != address(0), "Post owner does not exist"); - userToPostLikes[msg.sender][_postID] = true; - postToLikes[_postID]++; - // Transfer 1 USDC to the post owner + bool sent = mockUSDC.transferFrom(msg.sender, postOwner, 1 * 1e6); + require(sent, "Failed to send USDC to the post owner"); // (bool sent,) = postOwner.call{ value: 1 ether }(""); // require(sent, "Failed to send USDC to the post owner"); + userToPostLikes[msg.sender][_postID] = true; + postToLikes[_postID]++; + emit PostLiked(_postID, msg.sender, block.timestamp); } @@ -182,9 +186,9 @@ contract PunkSociety is Ownable { function commentOnPost(uint256 _postID, string memory _text) public { _requirePostExists(_postID); - // set max length at 250 characters + // set max length at 140 characters require( - bytes(_text).length <= 250, "Comment must be less than 250 characters" + bytes(_text).length <= 140, "Comment must be 140 characters or less" ); uint256 commentIndex = postToComments[_postID].length; postToComments[_postID].push(Comment(msg.sender, _text, commentIndex)); diff --git a/packages/nextjs/app/create/_components/MintingButtons.tsx b/packages/nextjs/app/create/_components/MintingButtons.tsx index 074caa6..dca7f33 100644 --- a/packages/nextjs/app/create/_components/MintingButtons.tsx +++ b/packages/nextjs/app/create/_components/MintingButtons.tsx @@ -1,7 +1,10 @@ -import { useState } from "react"; -// import { parseEther } from "viem"; +import { useEffect, useState } from "react"; +import Image from "next/image"; import { useAccount } from "wagmi"; -import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth"; +// import { parseEther } from "viem"; +import Modal from "~~/components/punk-society/Modal"; +import { InputBase } from "~~/components/scaffold-eth"; +import { useDeployedContractInfo, useScaffoldReadContract, useScaffoldWriteContract } from "~~/hooks/scaffold-eth"; import { uploadToPinata } from "~~/utils/pinata-upload"; import { notification } from "~~/utils/scaffold-eth"; @@ -16,10 +19,72 @@ interface MintingFormProps { } export const MintingButtons: React.FC = ({ yourJSON, resetForm, onPostCreated }) => { + const [showModal, setShowModal] = useState(false); + const [loading, setLoading] = useState(false); + const [allowanceAmount, setAllowanceAmount] = useState(); + const { address: connectedAddress } = useAccount(); const { writeContractAsync } = useScaffoldWriteContract("PunkSociety"); + const { writeContractAsync: USDCwriteContractAsync } = useScaffoldWriteContract("MockUSDC"); - const [loading, setLoading] = useState(false); + const { data: punkSocietyContractData } = useDeployedContractInfo("PunkSociety"); + + const { data: allowance } = useScaffoldReadContract({ + contractName: "MockUSDC", + functionName: "allowance", + args: [connectedAddress, punkSocietyContractData?.address], + watch: true, + }); + + const { data: balanceOf } = useScaffoldReadContract({ + contractName: "MockUSDC", + functionName: "balanceOf", + args: [connectedAddress], + watch: true, + }); + + const formattedUsdcBalance = balanceOf ? (Number(balanceOf.toString()) / 1e6).toFixed(2) : "0.00"; + + useEffect(() => { + if (allowance && parseInt(allowance.toString()) < 3000000) { + setShowModal(true); + } + }, [allowance]); + + const handleCloseModal = () => { + setShowModal(false); + }; + + const handleAllowanceChange = async () => { + if (!connectedAddress) { + notification.error("Please connect your wallet"); + return; + } + + // setLoading(true); + + try { + // const ipfsPath = await uploadToIPFS(); + + const contractResponse = await USDCwriteContractAsync({ + functionName: "approve", + args: [punkSocietyContractData?.address, allowanceAmount ? BigInt(allowanceAmount * 1e6) : BigInt(0)], + // value: parseEther("3"), + }); + + if (contractResponse) { + notification.success("Allowance increased successfully!"); + } + // resetForm(); + // onPostCreated(); + } catch (error) { + console.error("Error increasing allowance:", error); + notification.error("Increasing allowance failed, please try again."); + } finally { + setShowModal(false); + // setLoading(false); + } + }; const uploadToIPFS = async () => { // const notificationId = notification.loading("Uploading to Pinata..."); @@ -70,12 +135,38 @@ export const MintingButtons: React.FC = ({ yourJSON, resetForm }; return ( -
-
- + <> +
+
+ {/* {allowance?.toString()} */} + +
-
+ {showModal && ( + +
+

Insufficient USDC Allowance!

+ Please increase your USDC allowance to use the platform. + + Current Balance:{" "} + + USDC + {formattedUsdcBalance} + + + +
+ +
+ {/* */} + {/* Add your logic to increase the allowance here */} +
+
+ )} + ); }; diff --git a/packages/nextjs/components/punk-society/PunkConnectButton/AddressInfoDropdown.tsx b/packages/nextjs/components/punk-society/PunkConnectButton/AddressInfoDropdown.tsx index 771653e..3f4fdc1 100644 --- a/packages/nextjs/components/punk-society/PunkConnectButton/AddressInfoDropdown.tsx +++ b/packages/nextjs/components/punk-society/PunkConnectButton/AddressInfoDropdown.tsx @@ -1,6 +1,6 @@ import { useRef, useState } from "react"; import Link from "next/link"; -import { PunkBalance } from "../PunkBalance"; +// import { PunkBalance } from "../PunkBalance"; import { NetworkOptions } from "./NetworkOptions"; // import { FundButton, getOnrampBuyUrl } from "@coinbase/onchainkit/fund"; import { getAddress } from "viem"; @@ -82,7 +82,7 @@ export const AddressInfoDropdown = ({ address }: AddressInfoDropdownProps) => { >