From 286700a13eae3c6b810e982e8e5e7637c8fbf3ec Mon Sep 17 00:00:00 2001 From: Gizmotronn Date: Fri, 6 Jan 2023 00:49:00 +1100 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=8E=88=F0=9F=92=B8=20=E2=86=9D=20Add?= =?UTF-8?q?=20new=20lib=20file=20for=20creating=20posts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../frontend/components/Navigation/Sidebar.js | 24 +- Server/frontend/constants/contracts.ts | 1208 +++++++++++++++++ Server/frontend/lib/helpers.ts | 24 + Server/frontend/lib/useCreatePost.ts | 8 + Server/frontend/lib/useFollow.ts | 62 + Server/frontend/package.json | 8 +- Server/frontend/pages/_app.tsx | 5 - .../frontend/pages/api/auth/[...thirdweb].js | 45 + .../frontend/pages/api/auth/[...thirdweb].ts | 43 - Server/frontend/pages/index.tsx | 11 - Server/frontend/pages/profile/[id].tsx | 12 +- Server/frontend/styles/Create.module.css | 19 + Server/frontend/yarn.lock | 90 +- 13 files changed, 1484 insertions(+), 75 deletions(-) create mode 100644 Server/frontend/constants/contracts.ts create mode 100644 Server/frontend/lib/helpers.ts create mode 100644 Server/frontend/lib/useCreatePost.ts create mode 100644 Server/frontend/lib/useFollow.ts create mode 100644 Server/frontend/pages/api/auth/[...thirdweb].js delete mode 100644 Server/frontend/pages/api/auth/[...thirdweb].ts create mode 100644 Server/frontend/styles/Create.module.css diff --git a/Server/frontend/components/Navigation/Sidebar.js b/Server/frontend/components/Navigation/Sidebar.js index 6d807920..e4a74f4a 100644 --- a/Server/frontend/components/Navigation/Sidebar.js +++ b/Server/frontend/components/Navigation/Sidebar.js @@ -18,9 +18,23 @@ import { } from 'react-icons/fi'; import { IoPawOutline } from 'react-icons/io5'; import NavItem from './NavItem'; +import Link from 'next/link'; + +// Getting user data for sidebar +import { useAddress, useNetworkMismatch, useNetwork, ConnectWallet, ChainId, MediaRenderer } from '@thirdweb-dev/react'; +import useLensUser from '../../lib/auth/useLensUser'; +import useLogin from '../../lib/auth/useLogin'; +import SignInButton from '../SignInButton'; export default function Sidebar() { - const [navSize, changeNavSize] = useState("large") + const address = useAddress(); // Detect connected wallet + const isOnWrongNetwork = useNetworkMismatch(); // Is different to `activeChainId` in `_app.tsx` + const [, switchNetwork] = useNetwork(); // Switch network to `activeChainId` + const { isSignedInQuery, profileQuery } = useLensUser(); + const { mutate: requestLogin } = useLogin(); + + const [navSize, changeNavSize] = useState("small"); + return ( - - - + + + @@ -69,7 +83,7 @@ export default function Sidebar() { - + Liam Arbuckle @parselay.lens diff --git a/Server/frontend/constants/contracts.ts b/Server/frontend/constants/contracts.ts new file mode 100644 index 00000000..344d144c --- /dev/null +++ b/Server/frontend/constants/contracts.ts @@ -0,0 +1,1208 @@ +// 1. export the contract address +export const LENS_CONTRACT_ADDRESS = + "0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d"; + +// 2. export the contract abi +export const LENS_CONTRACT_ABI = [ + { + inputs: [ + { internalType: "address", name: "followNFTImpl", type: "address" }, + { internalType: "address", name: "collectNFTImpl", type: "address" }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { inputs: [], name: "CallerNotCollectNFT", type: "error" }, + { inputs: [], name: "CallerNotFollowNFT", type: "error" }, + { inputs: [], name: "CannotInitImplementation", type: "error" }, + { inputs: [], name: "EmergencyAdminCannotUnpause", type: "error" }, + { inputs: [], name: "InitParamsInvalid", type: "error" }, + { inputs: [], name: "Initialized", type: "error" }, + { inputs: [], name: "NotGovernance", type: "error" }, + { inputs: [], name: "NotGovernanceOrEmergencyAdmin", type: "error" }, + { inputs: [], name: "NotOwnerOrApproved", type: "error" }, + { inputs: [], name: "NotProfileOwner", type: "error" }, + { inputs: [], name: "NotProfileOwnerOrDispatcher", type: "error" }, + { inputs: [], name: "Paused", type: "error" }, + { inputs: [], name: "ProfileCreatorNotWhitelisted", type: "error" }, + { inputs: [], name: "ProfileImageURILengthInvalid", type: "error" }, + { inputs: [], name: "PublicationDoesNotExist", type: "error" }, + { inputs: [], name: "PublishingPaused", type: "error" }, + { inputs: [], name: "SignatureExpired", type: "error" }, + { inputs: [], name: "SignatureInvalid", type: "error" }, + { inputs: [], name: "ZeroSpender", type: "error" }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "approved", + type: "address", + }, + { + indexed: true, + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "operator", + type: "address", + }, + { indexed: false, internalType: "bool", name: "approved", type: "bool" }, + ], + name: "ApprovalForAll", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "from", type: "address" }, + { indexed: true, internalType: "address", name: "to", type: "address" }, + { + indexed: true, + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + ], + name: "approve", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "owner", type: "address" }], + name: "balanceOf", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "burn", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "tokenId", type: "uint256" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + name: "burnWithSig", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + ], + name: "collect", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "address", name: "collector", type: "address" }, + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.CollectWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "collectWithSig", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "contentURI", type: "string" }, + { + internalType: "uint256", + name: "profileIdPointed", + type: "uint256", + }, + { internalType: "uint256", name: "pubIdPointed", type: "uint256" }, + { internalType: "bytes", name: "referenceModuleData", type: "bytes" }, + { internalType: "address", name: "collectModule", type: "address" }, + { + internalType: "bytes", + name: "collectModuleInitData", + type: "bytes", + }, + { internalType: "address", name: "referenceModule", type: "address" }, + { + internalType: "bytes", + name: "referenceModuleInitData", + type: "bytes", + }, + ], + internalType: "struct DataTypes.CommentData", + name: "vars", + type: "tuple", + }, + ], + name: "comment", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "contentURI", type: "string" }, + { + internalType: "uint256", + name: "profileIdPointed", + type: "uint256", + }, + { internalType: "uint256", name: "pubIdPointed", type: "uint256" }, + { internalType: "bytes", name: "referenceModuleData", type: "bytes" }, + { internalType: "address", name: "collectModule", type: "address" }, + { + internalType: "bytes", + name: "collectModuleInitData", + type: "bytes", + }, + { internalType: "address", name: "referenceModule", type: "address" }, + { + internalType: "bytes", + name: "referenceModuleInitData", + type: "bytes", + }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.CommentWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "commentWithSig", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "string", name: "handle", type: "string" }, + { internalType: "string", name: "imageURI", type: "string" }, + { internalType: "address", name: "followModule", type: "address" }, + { + internalType: "bytes", + name: "followModuleInitData", + type: "bytes", + }, + { internalType: "string", name: "followNFTURI", type: "string" }, + ], + internalType: "struct DataTypes.CreateProfileData", + name: "vars", + type: "tuple", + }, + ], + name: "createProfile", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "wallet", type: "address" }], + name: "defaultProfile", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + { internalType: "uint256", name: "collectNFTId", type: "uint256" }, + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + ], + name: "emitCollectNFTTransferEvent", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "followNFTId", type: "uint256" }, + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + ], + name: "emitFollowNFTTransferEvent", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "exists", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256[]", name: "profileIds", type: "uint256[]" }, + { internalType: "bytes[]", name: "datas", type: "bytes[]" }, + ], + name: "follow", + outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "address", name: "follower", type: "address" }, + { internalType: "uint256[]", name: "profileIds", type: "uint256[]" }, + { internalType: "bytes[]", name: "datas", type: "bytes[]" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.FollowWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "followWithSig", + outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "getApproved", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + ], + name: "getCollectModule", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + ], + name: "getCollectNFT", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getCollectNFTImpl", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + ], + name: "getContentURI", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "getDispatcher", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getDomainSeparator", + outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "getFollowModule", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "getFollowNFT", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getFollowNFTImpl", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "getFollowNFTURI", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getGovernance", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "getHandle", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "getProfile", + outputs: [ + { + components: [ + { internalType: "uint256", name: "pubCount", type: "uint256" }, + { internalType: "address", name: "followModule", type: "address" }, + { internalType: "address", name: "followNFT", type: "address" }, + { internalType: "string", name: "handle", type: "string" }, + { internalType: "string", name: "imageURI", type: "string" }, + { internalType: "string", name: "followNFTURI", type: "string" }, + ], + internalType: "struct DataTypes.ProfileStruct", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "string", name: "handle", type: "string" }], + name: "getProfileIdByHandle", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + ], + name: "getPub", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "profileIdPointed", + type: "uint256", + }, + { internalType: "uint256", name: "pubIdPointed", type: "uint256" }, + { internalType: "string", name: "contentURI", type: "string" }, + { internalType: "address", name: "referenceModule", type: "address" }, + { internalType: "address", name: "collectModule", type: "address" }, + { internalType: "address", name: "collectNFT", type: "address" }, + ], + internalType: "struct DataTypes.PublicationStruct", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "getPubCount", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + ], + name: "getPubPointer", + outputs: [ + { internalType: "uint256", name: "", type: "uint256" }, + { internalType: "uint256", name: "", type: "uint256" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + ], + name: "getPubType", + outputs: [ + { internalType: "enum DataTypes.PubType", name: "", type: "uint8" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "uint256", name: "pubId", type: "uint256" }, + ], + name: "getReferenceModule", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "getState", + outputs: [ + { internalType: "enum DataTypes.ProtocolState", name: "", type: "uint8" }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "string", name: "name", type: "string" }, + { internalType: "string", name: "symbol", type: "string" }, + { internalType: "address", name: "newGovernance", type: "address" }, + ], + name: "initialize", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "address", name: "operator", type: "address" }, + ], + name: "isApprovedForAll", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "collectModule", type: "address" }, + ], + name: "isCollectModuleWhitelisted", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "followModule", type: "address" }, + ], + name: "isFollowModuleWhitelisted", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "profileCreator", type: "address" }, + ], + name: "isProfileCreatorWhitelisted", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "referenceModule", type: "address" }, + ], + name: "isReferenceModuleWhitelisted", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "mintTimestampOf", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { + internalType: "uint256", + name: "profileIdPointed", + type: "uint256", + }, + { internalType: "uint256", name: "pubIdPointed", type: "uint256" }, + { internalType: "bytes", name: "referenceModuleData", type: "bytes" }, + { internalType: "address", name: "referenceModule", type: "address" }, + { + internalType: "bytes", + name: "referenceModuleInitData", + type: "bytes", + }, + ], + internalType: "struct DataTypes.MirrorData", + name: "vars", + type: "tuple", + }, + ], + name: "mirror", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { + internalType: "uint256", + name: "profileIdPointed", + type: "uint256", + }, + { internalType: "uint256", name: "pubIdPointed", type: "uint256" }, + { internalType: "bytes", name: "referenceModuleData", type: "bytes" }, + { internalType: "address", name: "referenceModule", type: "address" }, + { + internalType: "bytes", + name: "referenceModuleInitData", + type: "bytes", + }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.MirrorWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "mirrorWithSig", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "ownerOf", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + name: "permit", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "address", name: "operator", type: "address" }, + { internalType: "bool", name: "approved", type: "bool" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + name: "permitForAll", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "contentURI", type: "string" }, + { internalType: "address", name: "collectModule", type: "address" }, + { + internalType: "bytes", + name: "collectModuleInitData", + type: "bytes", + }, + { internalType: "address", name: "referenceModule", type: "address" }, + { + internalType: "bytes", + name: "referenceModuleInitData", + type: "bytes", + }, + ], + internalType: "struct DataTypes.PostData", + name: "vars", + type: "tuple", + }, + ], + name: "post", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "contentURI", type: "string" }, + { internalType: "address", name: "collectModule", type: "address" }, + { + internalType: "bytes", + name: "collectModuleInitData", + type: "bytes", + }, + { internalType: "address", name: "referenceModule", type: "address" }, + { + internalType: "bytes", + name: "referenceModuleInitData", + type: "bytes", + }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.PostWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "postWithSig", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + ], + name: "safeTransferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + { internalType: "bytes", name: "_data", type: "bytes" }, + ], + name: "safeTransferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "operator", type: "address" }, + { internalType: "bool", name: "approved", type: "bool" }, + ], + name: "setApprovalForAll", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "profileId", type: "uint256" }], + name: "setDefaultProfile", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "address", name: "wallet", type: "address" }, + { internalType: "uint256", name: "profileId", type: "uint256" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.SetDefaultProfileWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "setDefaultProfileWithSig", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "address", name: "dispatcher", type: "address" }, + ], + name: "setDispatcher", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "address", name: "dispatcher", type: "address" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.SetDispatcherWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "setDispatcherWithSig", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "newEmergencyAdmin", type: "address" }, + ], + name: "setEmergencyAdmin", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "address", name: "followModule", type: "address" }, + { internalType: "bytes", name: "followModuleInitData", type: "bytes" }, + ], + name: "setFollowModule", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "address", name: "followModule", type: "address" }, + { + internalType: "bytes", + name: "followModuleInitData", + type: "bytes", + }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.SetFollowModuleWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "setFollowModuleWithSig", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "followNFTURI", type: "string" }, + ], + name: "setFollowNFTURI", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "followNFTURI", type: "string" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.SetFollowNFTURIWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "setFollowNFTURIWithSig", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "newGovernance", type: "address" }, + ], + name: "setGovernance", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "imageURI", type: "string" }, + ], + name: "setProfileImageURI", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "profileId", type: "uint256" }, + { internalType: "string", name: "imageURI", type: "string" }, + { + components: [ + { internalType: "uint8", name: "v", type: "uint8" }, + { internalType: "bytes32", name: "r", type: "bytes32" }, + { internalType: "bytes32", name: "s", type: "bytes32" }, + { internalType: "uint256", name: "deadline", type: "uint256" }, + ], + internalType: "struct DataTypes.EIP712Signature", + name: "sig", + type: "tuple", + }, + ], + internalType: "struct DataTypes.SetProfileImageURIWithSigData", + name: "vars", + type: "tuple", + }, + ], + name: "setProfileImageURIWithSig", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "enum DataTypes.ProtocolState", + name: "newState", + type: "uint8", + }, + ], + name: "setState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "", type: "address" }], + name: "sigNonces", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "bytes4", name: "interfaceId", type: "bytes4" }], + name: "supportsInterface", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "index", type: "uint256" }], + name: "tokenByIndex", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "tokenDataOf", + outputs: [ + { + components: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "uint96", name: "mintTimestamp", type: "uint96" }, + ], + internalType: "struct IERC721Time.TokenData", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "uint256", name: "index", type: "uint256" }, + ], + name: "tokenOfOwnerByIndex", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }], + name: "tokenURI", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "tokenId", type: "uint256" }, + ], + name: "transferFrom", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "collectModule", type: "address" }, + { internalType: "bool", name: "whitelist", type: "bool" }, + ], + name: "whitelistCollectModule", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "followModule", type: "address" }, + { internalType: "bool", name: "whitelist", type: "bool" }, + ], + name: "whitelistFollowModule", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "profileCreator", type: "address" }, + { internalType: "bool", name: "whitelist", type: "bool" }, + ], + name: "whitelistProfileCreator", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "referenceModule", type: "address" }, + { internalType: "bool", name: "whitelist", type: "bool" }, + ], + name: "whitelistReferenceModule", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +]; \ No newline at end of file diff --git a/Server/frontend/lib/helpers.ts b/Server/frontend/lib/helpers.ts new file mode 100644 index 00000000..f908ee9f --- /dev/null +++ b/Server/frontend/lib/helpers.ts @@ -0,0 +1,24 @@ +import { ThirdwebSDK } from "@thirdweb-dev/sdk"; +import { EIP712Domain } from "@thirdweb-dev/sdk/dist/declarations/src/evm/common/sign"; +import { ethers } from "ethers"; +import omitDeep from "omit-deep"; + +export function omitTypename (object: any) { // Sign typed data with omitted __typename values using omit-deep + return omitDeep(object, ['__typename']) +}; + +export async function signTypedDataWithOmittedTypename (sdk: ThirdwebSDK, // Perform signing using SDK + domain: EIP712Domain, + types: Record, + value: Record, + ) { + return await sdk.wallet.signTypedData( + omitTypename(domain) as EIP712Domain, + omitTypename(types) as Record, + omitTypename(value) as Record, + ) +} + +export function splitSignature (signature: string) { // Split signature to extract v r s values + return ethers.utils.splitSignature(signature); +} \ No newline at end of file diff --git a/Server/frontend/lib/useCreatePost.ts b/Server/frontend/lib/useCreatePost.ts new file mode 100644 index 00000000..c5710d46 --- /dev/null +++ b/Server/frontend/lib/useCreatePost.ts @@ -0,0 +1,8 @@ +import { useMutation } from "@tanstack/react-query"; + +type CreatePostArgs = { // Consider adding more fields as described https://www.notion.so/skinetics/Lens-posting-a07f0e9c243249c0a3517e4160874137#1aa987be357644e596b1bd6b6cba88f9 + image: File; + title: string; + description: string; + content: string; +}; \ No newline at end of file diff --git a/Server/frontend/lib/useFollow.ts b/Server/frontend/lib/useFollow.ts new file mode 100644 index 00000000..02fa1284 --- /dev/null +++ b/Server/frontend/lib/useFollow.ts @@ -0,0 +1,62 @@ +import { useAddress, useSDK } from "@thirdweb-dev/react"; +import { useCreateFollowTypedDataMutation } from "../graphql/generated"; +import { omitTypename } from "@lens-protocol/api-bindings"; +import { signTypedDataWithOmittedTypename, splitSignature } from "./helpers"; +import { LENS_CONTRACT_ABI, LENS_CONTRACT_ADDRESS } from "../constants/contracts"; +import { useMutation } from "@tanstack/react-query"; +import useLogin from "./auth/useLogin"; + +export function useFollow () { + // Use mutation to get typed data for user to sign + const { mutateAsync: requestTypedData } = useCreateFollowTypedDataMutation(); + const sdk = useSDK(); + const address = useAddress(); + const { mutateAsync: loginUser } = useLogin(); + + async function follow (userId: string) { // which user we want to follow + await loginUser(); + const typedData = await requestTypedData({ + request: { + follow: [ + { + profile: userId, + }, + ], + }, + }); + + const { domain, types, value } = typedData.createFollowTypedData.typedData; + if (!sdk) return; + + // Ask user to sign using @Thirdweb-dev/sdk + const signature = await signTypedDataWithOmittedTypename ( + sdk, + domain, + types, + value + ); + + const { v, r, s } = splitSignature( signature.signature ); + + // Send typed data to smart contract + const lensHubContract = await sdk.getContractFromAbi ( + LENS_CONTRACT_ADDRESS, + LENS_CONTRACT_ABI + ); + + // Call contract function `followWithSig` + const result = await lensHubContract.call('followWithSig', { + follower: address, + profileIds: [userId], + datas: value.datas, + sig: { + v, + r, + s, + deadline: value.deadline, + }, + }); + }; + + return useMutation(follow); +}; \ No newline at end of file diff --git a/Server/frontend/package.json b/Server/frontend/package.json index 04cb20f5..130ae28f 100644 --- a/Server/frontend/package.json +++ b/Server/frontend/package.json @@ -16,9 +16,11 @@ "@emotion/styled": "^11", "@headlessui/react": "^1.7.7", "@lens-protocol/react": "^0.1.1", - "@supabase/supabase-js": "^2.2.2", + "@supabase/auth-helpers-nextjs": "^0.5.2", + "@supabase/auth-helpers-react": "^0.3.1", + "@supabase/supabase-js": "^2.2.3", "@tanstack/react-query": "^4.20.4", - "@thirdweb-dev/auth": "^2.0.38", + "@thirdweb-dev/auth": "^2.0.39", "@thirdweb-dev/react": "^3.6.8", "@thirdweb-dev/sdk": "^3.6.8", "@thirdweb-dev/storage": "^1.0.6", @@ -28,6 +30,7 @@ "moralis": "^2.10.3", "moralis-v1": "^1.12.0", "next": "13.1.0", + "omit-deep": "^0.3.0", "react": "18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.41.3", @@ -46,6 +49,7 @@ "@graphql-codegen/typescript-react-query": "^4.0.6", "@types/cookie": "^0.5.1", "@types/node": "^17.0.35", + "@types/omit-deep": "^0.3.0", "@types/react": "^17.0.45", "@types/react-syntax-highlighter": "^15.5.5", "autoprefixer": "^10.4.13", diff --git a/Server/frontend/pages/_app.tsx b/Server/frontend/pages/_app.tsx index faa4315c..b6c316ab 100644 --- a/Server/frontend/pages/_app.tsx +++ b/Server/frontend/pages/_app.tsx @@ -5,11 +5,6 @@ import { MoralisProvider } from "react-moralis"; import Header from "../components/Header"; import { ChakraProvider } from '@chakra-ui/react'; -/*import Navbar from './lens/components/Navbar'; -import { LensProvider } from '../context/lensContext'; -import { ApolloProvider } from "@apollo/client"; -import { lensClient } from './lens/constants/lensConstants';*/ - function MyApp({ Component, pageProps }: AppProps) { const AnyComponent = Component as any; const activeChainId = ChainId.Polygon; // Set to `.Mumbai` for testnet interaction diff --git a/Server/frontend/pages/api/auth/[...thirdweb].js b/Server/frontend/pages/api/auth/[...thirdweb].js new file mode 100644 index 00000000..818a9dd3 --- /dev/null +++ b/Server/frontend/pages/api/auth/[...thirdweb].js @@ -0,0 +1,45 @@ +import { ThirdwebAuth } from '@thirdweb-dev/auth'; +import { createClient } from '@supabase/supabase-js'; + +const supabase = createClient( + process.env.SUPABASE_URL || "", + process.env.SUPABASE_SERVICE_ROLE || "", +); + +const login = async (address) => { + const { data: user } = await supabase + .from("users") + .select("*") + .eq("address", address.toLowerCase()) + .single(); + + if (!user) { + const res = await supabase + .from("users") + .insert({ address: address.toLowerCase() }) + .single(); + + if (res.error) { + throw new Error("Failed to create user!"); + } + }; +} + +const user = async (address) => { + // Fetch the user data in our DB associated with the specified address + const { data: user } = await supabase + .from("users") + .select("*") + .eq("address", address.toLowerCase()) + .single(); + + return user; +}; + +export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({ + privateKey: process.env.ADMIN_PRIVATE_KEY || "", + domain: 'portal.skinetics.tech', + callbacks: { login, user }, +}); + +export default ThirdwebAuthHandler(); \ No newline at end of file diff --git a/Server/frontend/pages/api/auth/[...thirdweb].ts b/Server/frontend/pages/api/auth/[...thirdweb].ts deleted file mode 100644 index 95f76db0..00000000 --- a/Server/frontend/pages/api/auth/[...thirdweb].ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ThirdwebAuth } from "@thirdweb-dev/auth/next"; -import { createClient } from '@supabase/supabase-js'; - -export const supabase = createClient( - process.env.SUPABASE_URL || "", - process.env.SUPABASE_SERVICE_ROLE || "" -); - -export const { ThirdwebAuthHandler, getUser } = ThirdwebAuth({ - privateKey: process.env.PRIVATE_KEY || "", - domain: "sailors.skinetics.tech", - callbacks: { - login: async (address: string) => { - const { data: user } = await supabase - .from("users") - .select("*") - .eq("address", address.toLowerCase()) - .single(); - - if (!user) { - const res = await supabase - .from("users") - .insert({ address: address.toLowerCase() }) - .single(); - - if (res.error) { - throw new Error("Failed to create user!"); - } - } - }, - user: async (address: string) => { - const { data: user } = await supabase - .from("users") - .select("*") - .eq("address", address.toLowerCase()) - .single(); - - return user; - }, - }, -}); - -export default ThirdwebAuthHandler(); \ No newline at end of file diff --git a/Server/frontend/pages/index.tsx b/Server/frontend/pages/index.tsx index 04731750..8e291f0e 100644 --- a/Server/frontend/pages/index.tsx +++ b/Server/frontend/pages/index.tsx @@ -5,15 +5,7 @@ import { useState, useEffect } from "react"; import Sidebar from '../components/Navigation/Sidebar'; import { Flex, Text, IconButton } from '@chakra-ui/react'; -/* Proposals (Lens add-on) contract interaction -//import { useStateContext, /*getProposals*//* } from '../context/index'; -//import { useContract, useContractRead } from "@thirdweb-dev/react"; -//import allProposals from './api/proposals/fetchProposals';*/ - export default function Home () { - //console.log(allProposals); - - // Get publications from Lens const { isLoading, error, data } = useExplorePublicationsQuery({ request: { sortCriteria: PublicationSortCriteria.Latest, @@ -27,9 +19,6 @@ export default function Home () { refetchOnReconnect: false, }); - // Get proposals from contract (which will later be attached to Lens as a custom module) - - if (isLoading) { return (
Loading
) }; diff --git a/Server/frontend/pages/profile/[id].tsx b/Server/frontend/pages/profile/[id].tsx index 24bdc2c6..6106aa52 100644 --- a/Server/frontend/pages/profile/[id].tsx +++ b/Server/frontend/pages/profile/[id].tsx @@ -1,4 +1,4 @@ -import { MediaRenderer } from '@thirdweb-dev/react'; +import { MediaRenderer, Web3Button } from '@thirdweb-dev/react'; import { useRouter } from 'next/router'; import React from 'react'; import FeedPost from '../../components/FeedPost'; @@ -6,12 +6,15 @@ import { useProfileQuery, usePublicationsQuery } from '../../graphql/generated'; import styles from '../../styles/Profile.module.css'; import { Flex, Text, IconButton } from '@chakra-ui/react'; import Sidebar from '../../components/Navigation/Sidebar'; +import { LENS_CONTRACT_ABI, LENS_CONTRACT_ADDRESS } from '../../constants/contracts'; +import { useFollow } from '../../lib/useFollow'; type Props = {} export default function ProfilePage({}: Props) { const router = useRouter(); - const { id } = router.query; + const { id } = router.query; + const { mutate: followUser } = useFollow(); const { isLoading: loadingProfile, data: profileData, error: profileError } = useProfileQuery({ request: { handle: id, @@ -71,6 +74,11 @@ export default function ProfilePage({}: Props) {

{profileData?.profile?.bio}

{profileData?.profile?.stats.totalFollowers} Followers

+ followUser(profileData?.profile?.id)} + >Follow User
{ publicationsData?.publications.items.map((publication) => ( diff --git a/Server/frontend/styles/Create.module.css b/Server/frontend/styles/Create.module.css new file mode 100644 index 00000000..79911f93 --- /dev/null +++ b/Server/frontend/styles/Create.module.css @@ -0,0 +1,19 @@ +.container { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.formContainer { + max-width: 800px; +} + +.inputContainer { + width: 100%; + padding: 16px; + margin: 16px; + border-radius: 16px; + border: 1px solid white; +} \ No newline at end of file diff --git a/Server/frontend/yarn.lock b/Server/frontend/yarn.lock index 1c6261db..7ea22f99 100644 --- a/Server/frontend/yarn.lock +++ b/Server/frontend/yarn.lock @@ -3568,6 +3568,23 @@ rpc-websockets "^7.5.0" superstruct "^0.14.2" +"@supabase/auth-helpers-nextjs@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@supabase/auth-helpers-nextjs/-/auth-helpers-nextjs-0.5.2.tgz#54b0e097d4dd21ca8c0621865214dc46f75f26f5" + integrity sha512-B+sQFVEImAYOJKyyNX1DWqTF2qVf9SocOM1GD4eGHon6ulvLOo2a8V+v1jZAuLOBF6yzVIYnZucuYKZCiNP/Eg== + dependencies: + "@supabase/auth-helpers-shared" "0.2.3" + +"@supabase/auth-helpers-react@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@supabase/auth-helpers-react/-/auth-helpers-react-0.3.1.tgz#815493a294662c56b83c7dd51692dacd24329342" + integrity sha512-g3SFv08Dz9FapNif/ZY1b7qKGlMJDyTLSayHBz3kb3FuYxg7aLWgQtydDhm5AGbc0XtvpIBuhGTIOVevwpdosA== + +"@supabase/auth-helpers-shared@0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@supabase/auth-helpers-shared/-/auth-helpers-shared-0.2.3.tgz#da2cd1144f016c61b30ee6ac0da0f3dac7ccc99e" + integrity sha512-Xwnd2UQ/VTjTKIuVg1Xl/ryrElbSccOJhC11jbVPHOs7Y6yxzy9APxQs//jj4IpbDH4uOEDCdpMIJ0tzRxj9DQ== + "@supabase/functions-js@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@supabase/functions-js/-/functions-js-2.0.0.tgz#4ba0c9e6dff031e17666bef6779c48eff290a8a0" @@ -3604,7 +3621,7 @@ dependencies: cross-fetch "^3.1.5" -"@supabase/supabase-js@^2.2.2": +"@supabase/supabase-js@^2.2.3": version "2.2.3" resolved "https://registry.yarnpkg.com/@supabase/supabase-js/-/supabase-js-2.2.3.tgz#787639f14b5887d299839825aafa3f6a51dbff1b" integrity sha512-UOKnbkwtCGpI/yoW5FbiDqV1tvtP+kJkYROosCGS7M+EAaNhklNYaU3l3wNfxpR5LW7wOO1O17cb+5CSRjv/zg== @@ -3641,7 +3658,7 @@ "@tanstack/query-core" "4.20.9" use-sync-external-store "^1.2.0" -"@thirdweb-dev/auth@^2.0.38": +"@thirdweb-dev/auth@^2.0.39": version "2.0.39" resolved "https://registry.yarnpkg.com/@thirdweb-dev/auth/-/auth-2.0.39.tgz#152b3457d4b9bf1e6c819b3ee953dc86f1a5647f" integrity sha512-nXI/Z+nzOnFWwSKcqKeONiqCcInqb0YhlLXYfKSAhf2IVQiXX6ca944MCNTp3u/8alu6k2lQj1fk+Sbcq53Ucw== @@ -3996,6 +4013,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.45.tgz#2c0fafd78705e7a18b7906b5201a522719dc5190" integrity sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw== +"@types/omit-deep@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/omit-deep/-/omit-deep-0.3.0.tgz#d4ed3d1c4dd85e74cb72ce7d9dcd41296fb3b975" + integrity sha512-jwMkEElSsK+1VwtaYjb4aYYGMkVHfXWcJj2Zb7i3aEecaVLbIJvJNjpXYX1JVnIm4V4fcrUobhOjl9cXnfLXkA== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -7717,6 +7739,11 @@ get-tsconfig@^4.2.0: resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.3.0.tgz#4c26fae115d1050e836aea65d6fe56b507ee249b" integrity sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ== +get-value@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -7930,6 +7957,20 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -8374,6 +8415,13 @@ is-plain-obj@^4.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== +is-plain-object@^2.0.1: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -8474,21 +8522,33 @@ isarray@0.0.1: resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isarray@^2.0.1: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + isomorphic-fetch@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" @@ -9747,6 +9807,14 @@ oboe@2.1.5: dependencies: http-https "^1.0.0" +omit-deep@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/omit-deep/-/omit-deep-0.3.0.tgz#21c8af3499bcadd29651a232cbcacbc52445ebec" + integrity sha512-Lbl/Ma59sss2b15DpnWnGmECBRL8cRl/PjPbPMVW+Y8zIQzRrwMaI65Oy6HvxyhYeILVKBJb2LWeG81bj5zbMg== + dependencies: + is-plain-object "^2.0.1" + unset-value "^0.1.1" + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -11774,6 +11842,14 @@ unload@^2.3.1: resolved "https://registry.yarnpkg.com/unload/-/unload-2.4.1.tgz#b0c5b7fb44e17fcbf50dcb8fb53929c59dd226a5" integrity sha512-IViSAm8Z3sRBYA+9wc0fLQmU9Nrxb16rcDmIiR6Y9LJSZzI7QY5QsDhqPpKOjAn0O9/kfK1TfNEMMAGPTIraPw== +unset-value@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-0.1.2.tgz#506810b867f27c2a5a6e9b04833631f6de58d310" + integrity sha512-yhv5I4TsldLdE3UcVQn0hD2T5sNCPv4+qm/CTUpRKIpwthYRIipsAPdsrNpOI79hPQa0rTTeW22Fq6JWRcTgNg== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + update-browserslist-db@^1.0.9: version "1.0.10" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" From c77311eea7b4d734ca48e3ccc7cb582fedf911d3 Mon Sep 17 00:00:00 2001 From: Gizmotronn Date: Sun, 8 Jan 2023 19:40:10 +1100 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=92=A5=F0=9F=8E=88=20=E2=86=9D=20Addi?= =?UTF-8?q?ng=20context=20taken=20out=20in=20prev=20commit,=20and=20updati?= =?UTF-8?q?ng=20docs=20links?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 50 ++-- .../index.ts => constants/proposals.ts} | 2 +- .../index.jsx => context/proposals.jsx} | 2 +- Server/frontend/contracts/proposal.sol | 65 +++++ ...{moralisHandler.jsx => MoralisHandler.jsx} | 0 .../api/auth/{flaskAuth.tsx => flaskAuth.js} | 0 .../{fetchProposals.js => fetchProposals.jsx} | 2 + .../frontend/pages/lens/components/Navbar.js | 16 -- .../pages/lens/components/PostContent.js | 10 - .../pages/lens/components/PostFeed.jsx | 27 -- .../pages/lens/components/WritePost.js | 130 --------- .../pages/lens/constants/contractConstants.js | 38 --- .../pages/lens/constants/lensConstants.js | 253 ------------------ .../pages/lens/context/lensContext.js | 98 ------- Server/frontend/pages/lens/index.jsx | 52 ---- .../pages/lens/posts/[publicationId].jsx | 42 --- Server/frontend/pages/lens/write-post.jsx | 5 - 17 files changed, 94 insertions(+), 698 deletions(-) rename Server/frontend/{pages/api/proposals/constants/index.ts => constants/proposals.ts} (94%) rename Server/frontend/{pages/api/proposals/context/index.jsx => context/proposals.jsx} (95%) create mode 100644 Server/frontend/contracts/proposal.sol rename Server/frontend/pages/api/{moralisHandler.jsx => MoralisHandler.jsx} (100%) rename Server/frontend/pages/api/auth/{flaskAuth.tsx => flaskAuth.js} (100%) rename Server/frontend/pages/api/proposals/{fetchProposals.js => fetchProposals.jsx} (87%) delete mode 100644 Server/frontend/pages/lens/components/Navbar.js delete mode 100644 Server/frontend/pages/lens/components/PostContent.js delete mode 100644 Server/frontend/pages/lens/components/PostFeed.jsx delete mode 100644 Server/frontend/pages/lens/components/WritePost.js delete mode 100644 Server/frontend/pages/lens/constants/contractConstants.js delete mode 100644 Server/frontend/pages/lens/constants/lensConstants.js delete mode 100644 Server/frontend/pages/lens/context/lensContext.js delete mode 100644 Server/frontend/pages/lens/index.jsx delete mode 100644 Server/frontend/pages/lens/posts/[publicationId].jsx delete mode 100644 Server/frontend/pages/lens/write-post.jsx diff --git a/README.md b/README.md index dc651026..5b5decf2 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,26 @@ # sytizen-unity -[![.github/workflows/moralis.yml](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml/badge.svg?branch=ansible)](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml)
-Citizen Science (Sci-tizen) visualisation in the Unity.com engine - - -Check out our compass [here](http://ar.skinetics.tech/stellarios/compass) for more information about this product - -# Contracts - - View contract - - - - -## Trader branch -This branch contains a connection between Supabase (our current hosting platform for this backend) and the rest our our Notebooks & API. Everything else has been stripped out of this branch. - -Run `python3 -m venv .venv` to get started. - -Note: Start integrating in API from signal-k/polygon - -### Planti branch -Stripping everything out (e.g. `Ansible`/`Generator`) and just leaving the initial dashboard/game frontend. We'll merge it back with `Trader` later \ No newline at end of file +[![.github/workflows/moralis.yml](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml/badge.svg?branch=ansible)](https://github.com/Signal-K/sytizen/actions/workflows/moralis.yml) +[![Node.js CI](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml/badge.svg)](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml) +[![Node.js CI](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml/badge.svg?branch=wb3-7--interacting-with-anomalies-from-smart)](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml) +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/signal-k/sytizen/HEAD) +[![](https://github.com/Signal-K/sytizen/actions/workflows/node.js.yml/badge.svg?branch=wb3-7--interacting-with-anomalies-from-smart)](https://deepnote.com/workspace/star-sailors-49d2efda-376f-4329-9618-7f871ba16007/project/Supabase-Talk-ab6b31e5-13c3-4949-af38-1197d00bd4d1/notebook/Flask%20API-cb9219547b9e4e228b15cbf8a1aa9cf4#99de0381ef0d40ffaee2354354861bae) +[![](https://badges.thirdweb.com/contract?address=0xCcaA1ABA77Bae6296D386C2F130c46FEc3E5A004&theme=light&chainId=5)](https://thirdweb.com/goerli/0xCcaA1ABA77Bae6296D386C2F130c46FEc3E5A004?utm_source=contract_badge) + +# Signal-K/Sytizen Repo +## Related repositories +* [Signal-K/polygon](https://github.com/Signal-K/polygon/issues/26) ↝ Contract interactions +* [Signal-K/client](https://github.com/Signal-K/client) ↝ Frontend for interactions with our contracts + +## Documentation +All documentation is visible on [Notion](https://www.notion.so/skinetics/Sample-Planets-Contract-4c3bdcbca4b9450382f9cc4e72e081f7) + +# Citizen Science Classifications +## Process +* User mints an anomaly that has appeared in their UI (for now, the webapp, later it will be the game as well) +* API searches for a token that has already been lazy minted with the TIC id of the anomaly (or the identifier of the candidate) + * If there is a token id that has the TIC Id, then claim a copy of that to the `msg.sender` (player’s address) so they can manipulate it in-game + * If the TIC ID has never been minted before, lazy mint a new one with parameters fetched from the data source and send it to `msg.sender` + * Return the IPFS metadata +* Add some buttons that allow manipulations for the NFT (e.g. viewing (reading) metadata (e.g. image/video files, graphs). + * Graphs should be generated in a Jupyter notebook and returned in the Next app. +* User creates post (proposal [Proposal Board → Migration from Vite](https://www.notion.so/Proposal-Board-Migration-from-Vite-2e3ef95e384d4ac1875e0dbbe9a59337)) with the NFT ID for their anomaly and some extra metadata for their discoveries and proposal, and then users can vote \ No newline at end of file diff --git a/Server/frontend/pages/api/proposals/constants/index.ts b/Server/frontend/constants/proposals.ts similarity index 94% rename from Server/frontend/pages/api/proposals/constants/index.ts rename to Server/frontend/constants/proposals.ts index 112c2e12..2055c405 100644 --- a/Server/frontend/pages/api/proposals/constants/index.ts +++ b/Server/frontend/constants/proposals.ts @@ -1,6 +1,6 @@ import { createCampaign, dashboard, logout, payment, profile, withdraw } from '../../../../assets'; -export const navlinks = [ +export const navlinksProposals = [ { name: 'dashboard', imgUrl: dashboard, diff --git a/Server/frontend/pages/api/proposals/context/index.jsx b/Server/frontend/context/proposals.jsx similarity index 95% rename from Server/frontend/pages/api/proposals/context/index.jsx rename to Server/frontend/context/proposals.jsx index 71cc1c7e..7d60aaeb 100644 --- a/Server/frontend/pages/api/proposals/context/index.jsx +++ b/Server/frontend/context/proposals.jsx @@ -5,7 +5,7 @@ import { ethers } from 'ethers'; const StateContext = createContext(); export const StateContextProvider = ({ children }) => { - const { contract } = useContract('0xCcaA1ABA77Bae6296D386C2F130c46FEc3E5A004'); + const { contract } = useContract('0xed6e837Fda815FBf78E8E7266482c5Be80bC4bF9'); // Goerli contract -> will update to Polygon mainnet when in production const { mutateAsync: createProposal } = useContractWrite(contract, 'createProposal'); // Call function & create a proposal, passing in params from the form const address = useAddress(); const connect = useMetamask(); diff --git a/Server/frontend/contracts/proposal.sol b/Server/frontend/contracts/proposal.sol new file mode 100644 index 00000000..7fdafc6c --- /dev/null +++ b/Server/frontend/contracts/proposal.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +contract ClassificationProposal { + struct Classification { + // What types will this struct/campaign have? + address owner; + string title; // Title of the Proposal, type string + string description; + uint256 target; // How many coins to get the proposal to pass? + uint256 deadline; + uint256 amountCollected; // Goes towards target + string image; // image uri/url + address[] voters; + uint256[] votes; // Consider adding more components to match discussion in wb3-5 task + } + + mapping(uint256 => Classification) public classifications; + uint256 public numberOfClassifications = 0; + + function createProposal(address _owner, string memory _title, string memory _description, uint256 _target, uint256 _deadline, string memory _image) public returns (uint256) { // Returns id of the classification's proposal + Classification storage classification = classifications[numberOfClassifications]; // Populates the classifications array + require(classification.deadline < block.timestamp, "The deadline should be a date in the future"); // Maybe add another modifier to specify a minimum deadline period e.g. 1 day + + classification.owner = _owner; + classification.title = _title; + classification.description = _description; + classification.target = _target; + classification.deadline = _deadline; + classification.amountCollected = 0; + classification.image = _image; + + numberOfClassifications++; + + return numberOfClassifications - 1; + } + + function voteForProposal(uint256 _id) public payable { // Some crypto will be sent with the classificationID used as a param + uint256 amount = msg.value; // This amount is set by user (typically in frontend); the amount they'll be pledging towards a classification + Classification storage classification = classifications[_id]; + + classification.voters.push(msg.sender); // Push the address of user who voted + classification.votes.push(amount); // Amount of custom erc20 token pledged + + (bool sent,) = payable(classification.owner).call{value: amount}(""); + if (sent) { + classification.amountCollected = classification.amountCollected + amount; + } + } + + function getVoters(uint256 _id) view public returns(address[] memory, uint256[] memory) { // Array of votes and number of voters + return (classifications[_id].voters, classifications[_id].votes); + } + + function getProposals() public view returns(Classification[] memory) { // Retrieved from memory + Classification[] memory allClassifications = new Classification[](numberOfClassifications); // Empty array of empty structs referencing each classification/proposal + + for (uint i = 0; i < numberOfClassifications; i++) { + Classification storage item = classifications[i]; + allClassifications[i] = item; // Fetch the classification from storage and populate it in allClassifications + } + + return allClassifications; + } +} \ No newline at end of file diff --git a/Server/frontend/pages/api/moralisHandler.jsx b/Server/frontend/pages/api/MoralisHandler.jsx similarity index 100% rename from Server/frontend/pages/api/moralisHandler.jsx rename to Server/frontend/pages/api/MoralisHandler.jsx diff --git a/Server/frontend/pages/api/auth/flaskAuth.tsx b/Server/frontend/pages/api/auth/flaskAuth.js similarity index 100% rename from Server/frontend/pages/api/auth/flaskAuth.tsx rename to Server/frontend/pages/api/auth/flaskAuth.js diff --git a/Server/frontend/pages/api/proposals/fetchProposals.js b/Server/frontend/pages/api/proposals/fetchProposals.jsx similarity index 87% rename from Server/frontend/pages/api/proposals/fetchProposals.js rename to Server/frontend/pages/api/proposals/fetchProposals.jsx index e38a5c39..e6857d94 100644 --- a/Server/frontend/pages/api/proposals/fetchProposals.js +++ b/Server/frontend/pages/api/proposals/fetchProposals.jsx @@ -1,3 +1,5 @@ +import { StateContextProvider } from "../../../context/proposals"; +import { NavLinkProposals } from '../../../constants/proposals'; /*import { useContract, useContractRead } from "@thirdweb-dev/react"; export default function fetchProposalFromContract () { diff --git a/Server/frontend/pages/lens/components/Navbar.js b/Server/frontend/pages/lens/components/Navbar.js deleted file mode 100644 index d38dd467..00000000 --- a/Server/frontend/pages/lens/components/Navbar.js +++ /dev/null @@ -1,16 +0,0 @@ -import { ConnectButton } from "web3uikit"; -import Link from "next/link"; - -export default function Navbar() { - return ( -
    -
  • Home
  • -
  • Create Proposal
  • -
  • -
    - -
    -
  • -
- ) -}; \ No newline at end of file diff --git a/Server/frontend/pages/lens/components/PostContent.js b/Server/frontend/pages/lens/components/PostContent.js deleted file mode 100644 index 874517a9..00000000 --- a/Server/frontend/pages/lens/components/PostContent.js +++ /dev/null @@ -1,10 +0,0 @@ -import ReactMarkdown from "react-markdown"; - -export default function PostContent({ post }) { - return ( -
-

{post.metadata.name}

- {post.metadata.content} -
- ) -} \ No newline at end of file diff --git a/Server/frontend/pages/lens/components/PostFeed.jsx b/Server/frontend/pages/lens/components/PostFeed.jsx deleted file mode 100644 index 5763bdac..00000000 --- a/Server/frontend/pages/lens/components/PostFeed.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import Link from "next/link"; - -export default function PostFeed({ posts }) { - return ( -
- {posts - ? posts.map((post) => ) - : null} -
- ); -} - -function PostItem({ post }) { - let imageURL; - if (post.metadata.image) { // IPFS gateway (URI/url) - imageURL = post.metadata.image.replace("ipfs://", 'https://ipfs.io/ipfs'); // Replace ipfs link with a regular http ref.uri - } - - return ( -
- - -

{post.metadata.name}

- -
- ) -} \ No newline at end of file diff --git a/Server/frontend/pages/lens/components/WritePost.js b/Server/frontend/pages/lens/components/WritePost.js deleted file mode 100644 index d3d7a7e6..00000000 --- a/Server/frontend/pages/lens/components/WritePost.js +++ /dev/null @@ -1,130 +0,0 @@ -import { useForm } from "react-hook-form"; -import { useLensContext } from '../context/lensContext'; -import { - createContentMetadata, - getCreatePostQuery, // Compare to https://github.com/PatrickAlphaC/lens-blog - lensClient, - } from "../constants/lensConstants"; -import { useWeb3Contract } from "react-moralis"; -import lensAbi from '../contracts/lensABI.json'; -import { - lensHub, - networkConfig, - TRUE_BYTES, - } from "../constants/contractConstants"; - -const PINATA_PIN_ENDPOINT = 'https://api.pinata.cloud/pinning/pinJSONToIPFS'; - -async function pinMetadataToPinata ( - metadata, - contentName, - pinataApiKey, - pinataApiSecret -) { - console.log('pinning metadata to pinata'); - const data = JSON.stringify({ - pinataMetadata: { name: contentName }, - pinataContent: metadata, - }); - const config = { - method: "POST", - headers: { - "Content-Type": 'application/json', - pinata_api_key: pinataApiKey, - pinata_secret_api_key: pinataApiSecret, - }, - body: data, - }; - const response = await fetch(PINATA_PIN_ENDPOINT, config); - const ipfsHash = (await response.json()).ipfsHash; - console.log(`Stored content metadata with ${ipfsHash}`); - return ipfsHash; -} - -function PostForm () { - const { profileId, token } = useLensContext(); - const { register, errors, handleSubmit, formState, reset, watch } = useForm({ - mode: 'onChange', - }); - const { runContractFunction } = useWeb3Contract(); - - const publishPost = async function ({ content, contentName, imageUri, imageType, pinataApiKey, pinataApiSecret }) { - let fullContentUri; - const contentMetadata = createContentMetadata(content, contentName, imageUri, imageType); - const metadataIpfsHash = await pinMetadataToPinata(contentMetadata, contentName, pinataApiKey, pinataApiSecret); - fullContentUri = `ipfs://${metadataIpfsHash}`; - console.log(fullContentUri); - - // Post IPFS hash to Lens/blockchain - const transactionParameters = [ - profileId, - fullContentUri, - '0x23b9467334bEb345aAa6fd1545538F3d54436e96', // Free collect module contract address on Polygon (for now, all posts will be able to be collected without a fee). - TRUE_BYTES, - '0x17317F96f0C7a845FFe78c60B10aB15789b57Aaa', // Follower only reference module - ]; - console.log(transactionParameters); - const transactionOptions = { - abi: lensAbi, - contractAddress: '0xDb46d1Dc155634FbC732f92E853b10B288AD5a1d', // Lens Hub proxy contract address - functionName: 'post', - params: { - vars: transactionParameters, - }, - }; - - await runContractFunction({ - params: transactionOptions, - onError: (error) => console.log(error), - }); - - return ( - "Hi" - ) - }; - - return ( -
- -