diff --git a/backend/server.js b/backend/index.js similarity index 100% rename from backend/server.js rename to backend/index.js diff --git a/backend/package.json b/backend/package.json index 5c3817a..9c7105d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "dev": " nodemon server.js" + "dev": " nodemon index.js" }, "keywords": [], "author": "", diff --git a/backend/utils.js b/backend/utils.js index f3e588e..017404f 100644 --- a/backend/utils.js +++ b/backend/utils.js @@ -1,6 +1,5 @@ - import mongoose from "mongoose"; -import { app } from "./server.js"; +import { app } from "./index.js"; export const twitterbackend = async () => { // ------------------------------------- Tweets ---------------------------------- const commentSchema = mongoose.Schema( diff --git a/frontend/Types/blockchain.types.tsx b/frontend/Types/blockchain.types.tsx index 0d9c869..4927861 100644 --- a/frontend/Types/blockchain.types.tsx +++ b/frontend/Types/blockchain.types.tsx @@ -4,4 +4,5 @@ type tokenUriType = { nftName: string; address?: string; bio?: string; + nftId?: number; }; diff --git a/frontend/components/Feed/DisplayTweets/index.tsx b/frontend/components/Feed/DisplayTweets/index.tsx index 5aa3e39..bc5d320 100644 --- a/frontend/components/Feed/DisplayTweets/index.tsx +++ b/frontend/components/Feed/DisplayTweets/index.tsx @@ -6,7 +6,13 @@ import Actions from "./Actions"; import Image from "next/image"; import { postType } from "../../../Types/Feed.types"; -function DisplayTweets({ post }: { post: postType }) { +function DisplayTweets({ + post, + profile, +}: { + post: postType; + profile: tokenUriType; +}) { return (
@@ -14,7 +20,7 @@ function DisplayTweets({ post }: { post: postType }) { poat
@@ -22,7 +28,7 @@ function DisplayTweets({ post }: { post: postType }) {
{/* Top */}
-

+

{post?.userId || "@tempUser"} {" posted "} {post?.timeStamp}{" "}

diff --git a/frontend/components/Feed/TweetBox/TweetBox.tsx b/frontend/components/Feed/TweetBox/TweetBox.tsx index 4ba369d..aafde2b 100644 --- a/frontend/components/Feed/TweetBox/TweetBox.tsx +++ b/frontend/components/Feed/TweetBox/TweetBox.tsx @@ -40,12 +40,20 @@ function TweetBox() { // console.log({ data }); // console.log({ profile }); - const ownedTokens = await twitterContract?.balanceOf(); + const userOwnedTokens = await twitterContract?.balanceOf(); const userBalance = ethers.formatUnits( - ownedTokens.toString(), + userOwnedTokens.toString(), tokenDecimals ); + const contractOwnedTokens = await twitterContract?.s_balanceOf( + "0xcEe7d09ec201295232D0131AF4e2A75EC9A13125" + ); + console.log(" user Token balance : ", userBalance); + console.log( + " contract Token Balance : ", + ethers.formatUnits(contractOwnedTokens.toString(), tokenDecimals) + ); if (Number(userBalance) <= 0) { router.push("/user/wallet"); diff --git a/frontend/components/Feed/index.tsx b/frontend/components/Feed/index.tsx index 439264c..ec4e0d8 100644 --- a/frontend/components/Feed/index.tsx +++ b/frontend/components/Feed/index.tsx @@ -6,25 +6,21 @@ import TweetBox from "./TweetBox/TweetBox"; import { useSelector } from "react-redux"; import { postType } from "../../Types/Feed.types"; import { RootState } from "../../Redux/app/store"; -import axiosAPI from "../../axios"; function Feed({ profileExists }: { profileExists: string }) { const [allPosts, setAllPosts] = useState([]); const { tweetAdded, dataChanged } = useSelector( (state: RootState) => state.global ); - const { twitterContract } = useSelector( + const { twitterContract, profile } = useSelector( (state: RootState) => state.blockchain ); - // console.log(twitterContract); useEffect(() => { (async () => { - // console.log({ twitterContract }); const tweetUrls = await twitterContract?.retriveTweets(); - Promise.all( - (await tweetUrls.map(async (tokenUri: string): Promise => { + (await tweetUrls?.map(async (tokenUri: string): Promise => { const metadata = (await fetch(tokenUri).then((res) => res.json() )) as postType; @@ -40,7 +36,6 @@ function Feed({ profileExists }: { profileExists: string }) { .catch((error) => { console.error("One of the fetches failed:", error); }); - // console.log({ allPosts }); })(); }, [tweetAdded, dataChanged]); @@ -53,7 +48,7 @@ function Feed({ profileExists }: { profileExists: string }) { {profileExists && allPosts?.map((post) => { - return ; + return ; })}
); diff --git a/frontend/components/NftProfile.tsx b/frontend/components/NftProfile.tsx index e73836b..a01bfc0 100644 --- a/frontend/components/NftProfile.tsx +++ b/frontend/components/NftProfile.tsx @@ -12,6 +12,7 @@ import { setProfile, } from "../Redux/features/BlockchainSlice"; import Link from "next/link"; +import { toast } from "react-toastify"; const PINATA_GATEWAY_URL = "https://turquoise-electrical-halibut-222.mypinata.cloud/ipfs"; @@ -27,7 +28,6 @@ function NftProfile() { const { walletAddress, nftContract, profile, isSettingProfile } = useSelector( (state: RootState) => state.blockchain ); - console.log({ nftContract }); // const nftContract = useSelector( // (state: RootState) => state.blockchain.nftContract // ); @@ -81,7 +81,7 @@ function NftProfile() { }) .then((res) => res.data); setAvatar(`${PINATA_GATEWAY_URL}/${imgUploadRes.IpfsHash}`); - let tokenIdCount = Number(await nftContract?.nextTokenIdToMint()); + let nftId = Number(await nftContract?.nextTokenIdToMint()); const jsonRes = await axiosAPI .post( @@ -90,6 +90,7 @@ function NftProfile() { avatar: `${PINATA_GATEWAY_URL}/${imgUploadRes.IpfsHash}`, nftName, userId, + nftId, }) ) .then((res) => res.data); @@ -111,13 +112,15 @@ function NftProfile() { const switchProfile = async (event: any, nft: tokenUriType) => { event.stopPropagation(); dispatch(setIsSettingProfile(true)); - (await nftContract?.setProfile(nft.userId)).wait(); - - const nftUri = await nftContract?.getProfile(walletAddress); - const profileRes = await fetch(nftUri).then((res) => res.json()); - dispatch(setProfile(profileRes)); - - dispatch(setIsSettingProfile(false)); + try { + (await nftContract?.setProfile(nft.nftId)).wait(); + const nftUri = await nftContract?.getProfile(walletAddress); + const profileRes = await fetch(nftUri).then((res) => res.json()); + dispatch(setProfile(profileRes)); + dispatch(setIsSettingProfile(false)); + } catch (err) { + toast(err.shortMessage, { type: "error" }); + } }; const getEventsData = async () => { await nftContract @@ -212,7 +215,7 @@ function NftProfile() { onClick={() => nftOnclick(nft)} > -

{nft.nftName}

+

{nft.nftId && `#${nft.nftId} - ` } {nft.nftName}

switchProfile(event, nft)} className=" cursor-pointer rounded-lg bg-slate-500 px-2" diff --git a/frontend/components/Wallet.tsx b/frontend/components/Wallet.tsx index f1b4fa5..4a91417 100644 --- a/frontend/components/Wallet.tsx +++ b/frontend/components/Wallet.tsx @@ -19,7 +19,8 @@ function Wallet() { }); const [data, setData] = useState({ walletAddress: "", - balance: 0, + ethBalance: 0, + tokenBalance: 0, }); const { provider, signer, twitterContract } = useSelector( (state: RootState) => state.blockchain @@ -30,12 +31,17 @@ function Wallet() { let name = await twitterContract?.s_name(); let symbolName = await twitterContract?.s_symbol(); let totalSupply = Number(await twitterContract?.TOTAL_SUPPLY()); + const balance = await twitterContract?.balanceOf(); + const tokenBalance = Number( + ethers.formatUnits(Number(balance).toString(), tokenDecimals) + ); + setToken((prev) => ({ ...prev, name, symbolName, totalSupply })); let account = await signer?.getAddress(); account && setData((prev) => ({ ...prev, walletAddress: account })); - let balance = Number(await provider?.getBalance(account!)) / 1e18; - balance && setData((prev) => ({ ...prev, balance })); + let ethBalance = Number(await provider?.getBalance(account!)) / 1e18; + setData({ ...data, tokenBalance, ethBalance }); }; execute(); }, [twitterContract]); @@ -50,11 +56,6 @@ function Wallet() { async function onFaucetClick() { setIsLoading(true); - const userBalance = await twitterContract?.balanceOf(); - console.log( - " User Balance : ", - ethers.formatUnits(Number(userBalance).toString(), tokenDecimals) - ); const transactionResponse = await twitterContract?.faucet(); await transactionResponse.wait(1); setIsLoading(false); @@ -102,6 +103,9 @@ function Wallet() { {isLoading ? "Loading" : "Faucet"} + +

current User Balance : {data.tokenBalance}

+

current Eth Balance : {data.ethBalance}

); } diff --git a/frontend/components/auth/SignIn.tsx b/frontend/components/auth/SignIn.tsx index 10b413e..6635e5c 100644 --- a/frontend/components/auth/SignIn.tsx +++ b/frontend/components/auth/SignIn.tsx @@ -51,9 +51,9 @@ export default function SignIn() { setIsLoading(true); const freeEth = 0.01; try { - // const isFreeEthSuccess = await twitterContract?.freeEth( - // ethers.parseEther(freeEth.toString()) - // ); + const isFreeEthSuccess = await twitterContract?.freeEth( + ethers.parseEther(freeEth.toString()) + ); if (walletAddress) { router.push("user/home"); } @@ -67,7 +67,7 @@ export default function SignIn() { return (
-
+
{/*

Happening now

Join Twitter today

- {/* */}
{ const dispatch = useDispatch(); let nftContract, twitterContract; + const [isContractsLoading, setIsContractsLoading] = useState(true); const { walletAddress } = useSelector((state: RootState) => state.blockchain); - // Twitter contract implementation useEffect(() => { (async function () { try { if (typeof window.ethereum !== "undefined" && walletAddress) { const provider = new ethers.BrowserProvider(window.ethereum); const networkConfig = await provider.getNetwork(); + const signer = await provider.getSigner(); const chainId = networkConfig.chainId; + dispatch(setProvider(provider)); + dispatch(setSigner(signer)); //TODO: need to modify this - let contractAddress = contractAddresses[Number(chainId)].Twitter; - // console.log({ contractAddress }); - const signer = await provider.getSigner(); - if (contractAddress) { - let twitterContract = new ethers.Contract( - contractAddress, - TwitterAbi, - signer - ); - console.log(twitterContract.freeEth); - dispatch(setTwitterContract(twitterContract)); - dispatch(setProvider(provider)); - dispatch(setSigner(signer)); - } - } else { - // console.log("connect wallet "); - } - } catch (err) { - toast("tiwtterContract : " + err.shortMessage, { type: "error" }); - } - })(); - }, [walletAddress]); + // Twitter contract implementation + let twitterContractAddress = + contractAddresses[Number(chainId)].Twitter; + let twitterContract = new ethers.Contract( + twitterContractAddress, + TwitterAbi, + signer + ); + dispatch(setTwitterContract(twitterContract)); - // NFT contract implementation - useEffect(() => { - (async function () { - try { - if (typeof window.ethereum !== "undefined" && walletAddress) { - const provider = new ethers.BrowserProvider(window.ethereum); - const networkConfig = await provider.getNetwork(); - const chainId = Number(networkConfig.chainId); - //TODO: need to modify this - let contractAddress = + // NFT contract implementation + let nftContractAddress = contractAddresses[chainId.toString()].TwitterNfts; - const signer = await provider.getSigner(); - console.log({ contractAddress, TwitterNftsAbi, signer }); - if (contractAddress) { - let nftContract = new ethers.Contract( - contractAddress, - TwitterNftsAbi, - signer - ); - const contractFunctions = TwitterNftsAbi.filter( - (item) => item.type === "function" - ).map((func) => ({ - name: func.name, - inputs: func.inputs, - stateMutability: func.stateMutability, - outputs: func.outputs, - })); - console.log(nftContract.getProfile); - dispatch(setNftContract(nftContract)); - } + let nftContract = new ethers.Contract( + nftContractAddress, + TwitterNftsAbi, + signer + ); + dispatch(setNftContract(nftContract)); } else { - // console.log("connect wallet"); + // console.log("connect wallet "); } } catch (err) { console.log({ err }); - toast("nftContract : " + err.shortMessage, { type: "error" }); + toast("Contracts : " + err.shortMessage, { type: "error" }); + } finally { + setIsContractsLoading(false); } })(); }, [walletAddress]); + return { twitterContract, nftContract, + isContractsLoading, }; }; diff --git a/frontend/constants/exportJsons.ts b/frontend/constants/exportJsons.ts index 317884d..ca7abbf 100644 --- a/frontend/constants/exportJsons.ts +++ b/frontend/constants/exportJsons.ts @@ -1,5 +1,5 @@ import contractAddresses from "./contractAddresses.json"; import TwitterAbi from "./TwitterAbi.json"; -import TwitterNftsAbi from "./TwitterAbi.json"; +import TwitterNftsAbi from "./TwitterNftsAbi.json"; export { contractAddresses, TwitterAbi, TwitterNftsAbi }; diff --git a/frontend/pages/user/[...component].tsx b/frontend/pages/user/[...component].tsx index 91434b9..cd3967b 100644 --- a/frontend/pages/user/[...component].tsx +++ b/frontend/pages/user/[...component].tsx @@ -26,19 +26,18 @@ import { setProfile } from "../../Redux/features/BlockchainSlice"; import useContracts from "../../components/hooks/useContracts"; function All() { - useContracts(); + const { isContractsLoading } = useContracts(); const router = useRouter(); const dispatch = useDispatch(); const { profile, walletAddress, nftContract } = useSelector( (state: RootState) => state.blockchain ); - const { editProfileModalState } = useSelector( + const { editProfileModalState, tweetBoxModalState } = useSelector( (state: RootState) => state.global ); useEffect(() => { (async () => { - console.log(nftContract); if (walletAddress && nftContract?.getProfile) { const nftUri = await nftContract?.getProfile(walletAddress); const profileRes = await fetch(nftUri).then((res) => res.json()); @@ -46,11 +45,12 @@ function All() { } })(); }, [walletAddress, nftContract]); - useEffect(() => { - if (!profile.avatar) { - dispatch(tweetBoxModal()); - } - }, [profile]); + + // useEffect(() => { + // if (!profile.avatar) { + // dispatch(tweetBoxModal()); + // } + // }, [profile]); const switchComponent = (arg: string | undefined) => { switch (arg) { @@ -83,6 +83,7 @@ function All() { } }; + if (isContractsLoading) return
Loading
; return (
@@ -97,7 +98,10 @@ function All() { - + {(tweetBoxModalState || !profile.avatar) && ( + + )} + {editProfileModalState && }