From 9d32efbab893c93889bfdf7084a8901a046a79ee Mon Sep 17 00:00:00 2001 From: 0xExp-po Date: Sun, 15 Sep 2024 19:00:29 +0900 Subject: [PATCH] feat: add check project in on-chain --- dapp/src/components/ProjectCard.jsx | 20 +++-- dapp/src/components/ProjectList.jsx | 114 ++++++++++++++++++++---- dapp/src/components/SetProject.astro | 12 +-- dapp/src/constants/demoConfigData.js | 70 +++++++-------- dapp/src/service/ReadContractService.ts | 20 +++++ 5 files changed, 173 insertions(+), 63 deletions(-) diff --git a/dapp/src/components/ProjectCard.jsx b/dapp/src/components/ProjectCard.jsx index a330c4b..d9876fc 100644 --- a/dapp/src/components/ProjectCard.jsx +++ b/dapp/src/components/ProjectCard.jsx @@ -32,10 +32,12 @@ const ProjectCard = ({ config }) => { githubLink: tomlData.DOCUMENTATION?.ORG_GITHUB || "", }, socialLinks: { - twitter: "", - telegram: "", - discord: "", - instagram: "", + ...(tomlData.DOCUMENTATION?.ORG_TWITTER && { twitter: tomlData.DOCUMENTATION.ORG_TWITTER }), + ...(tomlData.DOCUMENTATION?.ORG_TELEGRAM && { telegram: tomlData.DOCUMENTATION.ORG_TELEGRAM }), + ...(tomlData.DOCUMENTATION?.ORG_DISCORD && { discord: tomlData.DOCUMENTATION.ORG_DISCORD }), + ...(tomlData.DOCUMENTATION?.ORG_INSTAGRAM && { instagram: tomlData.DOCUMENTATION.ORG_INSTAGRAM }), + ...(tomlData.DOCUMENTATION?.ORG_FACEBOOK && { facebook: tomlData.DOCUMENTATION.ORG_FACEBOOK }), + ...(tomlData.DOCUMENTATION?.ORG_REDDIT && { reddit: tomlData.DOCUMENTATION.ORG_REDDIT }), }, authorGithubNames: tomlData.PRINCIPALS?.map((p) => p.github) || [], maintainersAddresses: tomlData.ACCOUNTS || [], @@ -69,8 +71,8 @@ const ProjectCard = ({ config }) => { />
-

{config.projectName}

-

{config.description}

+

{config.projectName || "No project name"}

+

{config.description || "No description"}

{config.officials.websiteLink && ( @@ -90,7 +92,11 @@ const ProjectCard = ({ config }) => { ) ))}
-

by {config.companyName}

+ {config.companyName ? ( +

by {config.companyName}

+ ) : ( +

No company name

+ )}
); diff --git a/dapp/src/components/ProjectList.jsx b/dapp/src/components/ProjectList.jsx index a35266f..8c2878d 100644 --- a/dapp/src/components/ProjectList.jsx +++ b/dapp/src/components/ProjectList.jsx @@ -6,14 +6,19 @@ import ProjectInfoModal from './utils/ProjectInfoModal.jsx'; import { getDemoConfigData } from '../constants/demoConfigData'; import { refreshLocalStorage, setProjectId, loadConfigData } from '../service/StateService'; import { projectCardModalOpen } from '../utils/store.js'; -import { convertGitHubLink } from '../utils/editLinkFunctions'; +import { convertGitHubLink, getAuthorRepo } from '../utils/editLinkFunctions'; +import { getProjectFromName } from '../service/ReadContractService'; +import { fetchTOMLFromConfigUrl } from '../service/GithubService'; const ProjectList = () => { const isProjectInfoModalOpen = useStore(projectCardModalOpen); const [projects, setProjects] = useState(undefined); const [filteredProjects, setFilteredProjects] = useState(undefined); const [searchTerm, setSearchTerm] = useState(''); - const [category, setCategory] = useState('all'); + const [isLoading, setIsLoading] = useState(false); + const [isInOnChain, setIsInOnChain] = useState(false); + const [configInfo, setConfigInfo] = useState(); + const [registerButtonVisible, setRegisterButtonVisible] = useState(false); const [isModalOpen, setModalOpen] = useState(false); const [projectInfo, setProjectInfo] = useState(null); @@ -38,13 +43,22 @@ const ProjectList = () => { useEffect(() => { if (projects) { + setRegisterButtonVisible(false); const filtered = projects.filter(project => - project?.projectName.toLowerCase().includes(searchTerm.toLowerCase()) && - (category === 'all') + project?.projectName.toLowerCase().includes(searchTerm.toLowerCase()) ); setFilteredProjects(filtered); + + if (searchTerm && filtered.length === 0) { + const timer = setTimeout(() => { + checkProjectOnChain(searchTerm); + setRegisterButtonVisible(true); + }, 1000); + + return () => clearTimeout(timer); + } } - }, [searchTerm, category, projects]); + }, [searchTerm, projects]); useEffect(() => { setModalOpen(isProjectInfoModalOpen); @@ -71,6 +85,65 @@ const ProjectList = () => { window.location.href = '/register'; } + const checkProjectOnChain = async (projectName) => { + console.log("search:", projectName); + setIsLoading(true); + try { + const project = await getProjectFromName(projectName); + if (project && project.name && project.config && project.maintainers) { + const tomlData = await fetchTOMLFromConfigUrl(project.config.url); + if (tomlData) { + const configData = { + projectName: project.name, + logoImageLink: tomlData.DOCUMENTATION?.ORG_LOGO || "", + thumbnailImageLink: tomlData.DOCUMENTATION?.ORG_THUMBNAIL || "", + description: tomlData.DOCUMENTATION?.ORG_DESCRIPTION || "", + companyName: tomlData.DOCUMENTATION?.ORG_NAME || "", + officials: { + websiteLink: tomlData.DOCUMENTATION?.ORG_URL || "", + githubLink: tomlData.DOCUMENTATION?.ORG_GITHUB || "", + }, + socialLinks: { + ...(tomlData.DOCUMENTATION?.ORG_TWITTER && { twitter: tomlData.DOCUMENTATION.ORG_TWITTER }), + ...(tomlData.DOCUMENTATION?.ORG_TELEGRAM && { telegram: tomlData.DOCUMENTATION.ORG_TELEGRAM }), + ...(tomlData.DOCUMENTATION?.ORG_DISCORD && { discord: tomlData.DOCUMENTATION.ORG_DISCORD }), + ...(tomlData.DOCUMENTATION?.ORG_INSTAGRAM && { instagram: tomlData.DOCUMENTATION.ORG_INSTAGRAM }), + ...(tomlData.DOCUMENTATION?.ORG_FACEBOOK && { facebook: tomlData.DOCUMENTATION.ORG_FACEBOOK }), + ...(tomlData.DOCUMENTATION?.ORG_REDDIT && { reddit: tomlData.DOCUMENTATION.ORG_REDDIT }), + }, + authorGithubNames: tomlData.PRINCIPALS?.map((p) => p.github) || [], + maintainersAddresses: tomlData.ACCOUNTS || [], + }; + setConfigInfo(configData); + } else { + // alert("Can not read config data."); + const configData = { + projectName: project.name, + logoImageLink: undefined, + thumbnailImageLink: "", + description: "", + companyName: "", + officials: { + githubLink: project.config.url, + }, + socialLinks: { + }, + authorGithubNames: [], + maintainersAddresses: project.maintainers, + }; + setConfigInfo(configData); + } + setIsInOnChain(true); + } else { + setIsInOnChain(false); + } + } catch (error) { + console.error('Error checking project on-chain:', error); + } finally { + setIsLoading(false); + } + }; + return (
@@ -89,7 +162,7 @@ const ProjectList = () => { >
-
+ {filteredProjects !== undefined && ( @@ -100,15 +173,26 @@ const ProjectList = () => { ))} ) : ( -
- {/*

No projects found

*/} - -
+ isLoading ? ( +
+

looking if the project is registered on chain...

+
+ ) : ( + isInOnChain ? ( + + ) : ( + registerButtonVisible && ( +
+ +
+ ) + ) + ) ) )} diff --git a/dapp/src/components/SetProject.astro b/dapp/src/components/SetProject.astro index da53bb4..a27f0e8 100644 --- a/dapp/src/components/SetProject.astro +++ b/dapp/src/components/SetProject.astro @@ -89,12 +89,12 @@ const TANSU_CONTRACT_ID = import.meta.env.PUBLIC_TANSU_CONTRACT_ID; githubLink: tomlData.DOCUMENTATION?.ORG_GITHUB || "", }, socialLinks: { - twitter: "", - telegram: "", - discord: "", - instagram: "", - facebook: "", - reddit: "", + ...(tomlData.DOCUMENTATION?.ORG_TWITTER && { twitter: tomlData.DOCUMENTATION.ORG_TWITTER }), + ...(tomlData.DOCUMENTATION?.ORG_TELEGRAM && { telegram: tomlData.DOCUMENTATION.ORG_TELEGRAM }), + ...(tomlData.DOCUMENTATION?.ORG_DISCORD && { discord: tomlData.DOCUMENTATION.ORG_DISCORD }), + ...(tomlData.DOCUMENTATION?.ORG_INSTAGRAM && { instagram: tomlData.DOCUMENTATION.ORG_INSTAGRAM }), + ...(tomlData.DOCUMENTATION?.ORG_FACEBOOK && { facebook: tomlData.DOCUMENTATION.ORG_FACEBOOK }), + ...(tomlData.DOCUMENTATION?.ORG_REDDIT && { reddit: tomlData.DOCUMENTATION.ORG_REDDIT }), }, authorGithubNames: tomlData.PRINCIPALS?.map((p: { github: any; }) => p.github) || [], maintainersAddresses: tomlData.ACCOUNTS || [], diff --git a/dapp/src/constants/demoConfigData.js b/dapp/src/constants/demoConfigData.js index a87b87a..303cac9 100644 --- a/dapp/src/constants/demoConfigData.js +++ b/dapp/src/constants/demoConfigData.js @@ -35,41 +35,41 @@ export const demoConfigData = [ "GDNSSYSCSSJ76FER5WEEXME5G4MTCUBKDRQSKOYP36KUKVDB2VCMERS6" ], }, - { - projectName: "salib", - logoImageLink: "https://raw.githubusercontent.com/SALib/SALib/main/docs/assets/logo.png", - description: "Python implementations of commonly used sensitivity analysis methods. Useful in systems modeling to calculate the effects of model inputs or exogenous factors on outputs of interest.", - companyName: " SALib", - officials: { - websiteLink: "http://salib.github.io/SALib/", - githubLink: "https://github.com/SALib/SALib", - }, - socialLinks: { - twitter: "https://twitter.com/", - instagram: "https://instagram.com/", - }, - authorGithubNames: ["ConnectedSystems","tupui"], - maintainersAddresses: [ - "GCUDW6ZF5SCGCMS3QUTELZ6LSAH6IVVXNRPRLAUNJ2XYLCA7KH7ZCVQS", - "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37" - ], - }, - { - projectName: "fff", - logoImageLink: "https://github.com/0xExp-po/soroban-versioning/blob/main/website/static/img/logo.svg", - description: "Bringing Git hashes onto Stellar’s blockchain", - companyName: "Consulting Manao GmbH", - officials: { - websiteLink: "https://tansu.dev", - githubLink: "https://github.com/0xExp-po/soroban-versioning", - }, - socialLinks: { - }, - authorGithubNames: ["0xExp-po"], - maintainersAddresses: [ - "GALDGLKIXR52A5EZTIRZ2IWEZ5PWN55IY2TLA7ORFPG2VVSFVV5PYNOB", - ], - }, + // { + // projectName: "salib", + // logoImageLink: "https://raw.githubusercontent.com/SALib/SALib/main/docs/assets/logo.png", + // description: "Python implementations of commonly used sensitivity analysis methods. Useful in systems modeling to calculate the effects of model inputs or exogenous factors on outputs of interest.", + // companyName: " SALib", + // officials: { + // websiteLink: "http://salib.github.io/SALib/", + // githubLink: "https://github.com/SALib/SALib", + // }, + // socialLinks: { + // twitter: "https://twitter.com/", + // instagram: "https://instagram.com/", + // }, + // authorGithubNames: ["ConnectedSystems","tupui"], + // maintainersAddresses: [ + // "GCUDW6ZF5SCGCMS3QUTELZ6LSAH6IVVXNRPRLAUNJ2XYLCA7KH7ZCVQS", + // "GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOKY3B2WSQHG4W37" + // ], + // }, + // { + // projectName: "fff", + // logoImageLink: "https://github.com/0xExp-po/soroban-versioning/blob/main/website/static/img/logo.svg", + // description: "Bringing Git hashes onto Stellar’s blockchain", + // companyName: "Consulting Manao GmbH", + // officials: { + // websiteLink: "https://tansu.dev", + // githubLink: "https://github.com/0xExp-po/soroban-versioning", + // }, + // socialLinks: { + // }, + // authorGithubNames: ["0xExp-po"], + // maintainersAddresses: [ + // "GALDGLKIXR52A5EZTIRZ2IWEZ5PWN55IY2TLA7ORFPG2VVSFVV5PYNOB", + // ], + // }, ]; export function getDemoConfigData() { diff --git a/dapp/src/service/ReadContractService.ts b/dapp/src/service/ReadContractService.ts index 9398dc9..ab2f19e 100644 --- a/dapp/src/service/ReadContractService.ts +++ b/dapp/src/service/ReadContractService.ts @@ -1,5 +1,9 @@ import Versioning from "../contracts/soroban_versioning"; import type { Project } from "soroban_versioning"; +import * as pkg from "js-sha3"; + +const { keccak256 } = pkg; +import { Buffer } from "buffer"; import {loadedProjectId} from "./StateService"; @@ -29,7 +33,23 @@ async function getProject(): Promise { return res.result; } +async function getProjectFromName(projectName: string): Promise { + const projectId = Buffer.from( + keccak256.create().update(projectName).digest(), + ); + + if (projectId === undefined) { + alert("No project defined"); + return; + } + const res = await Versioning.get_project({ + project_key: projectId, + }); + return res.result; +} + export { getProject, getProjectHash, + getProjectFromName, }; \ No newline at end of file