diff --git a/apps/potlock/widget/Cart/Checkout.jsx b/apps/potlock/widget/Cart/Checkout.jsx index ef9b3bd0..61a33899 100644 --- a/apps/potlock/widget/Cart/Checkout.jsx +++ b/apps/potlock/widget/Cart/Checkout.jsx @@ -19,6 +19,11 @@ const [projectId, setProjectId] = useState(""); // } // `; +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + +const registeredProjects = registry.getProjects(); + const Container = styled.div` background: #fafafa; display: flex; @@ -172,7 +177,7 @@ const allSelected = // } // }, [props.transactionHashes]); -if (props.transactionHashes && props.registeredProjects && !state.successfulDonationRecipientId) { +if (props.transactionHashes && registeredProjects && !state.successfulDonationRecipientId) { const body = JSON.stringify({ jsonrpc: "2.0", id: "dontcare", diff --git a/apps/potlock/widget/Components/Feed.jsx b/apps/potlock/widget/Components/Feed.jsx index 3db0b6de..5edeea5a 100644 --- a/apps/potlock/widget/Components/Feed.jsx +++ b/apps/potlock/widget/Components/Feed.jsx @@ -1,10 +1,13 @@ const { ownerId } = props; -const projects = props.registeredProjects || []; -const projectIds = useMemo( - () => projects.filter((project) => project.status === "Approved").map((project) => project.id), - [projects] -); +const PotlockRegistrySDK = VM.require(`${ownerId}/widget/SDK.registry`); +const registry = PotlockRegistrySDK({ env: props.env }); + +const projects = registry.getProjects() || []; + +const projectIds = projects + .filter((project) => project.status === "Approved") + .map((project) => project.id); const Container = styled.div` padding: 24px 64px; diff --git a/apps/potlock/widget/Index.jsx b/apps/potlock/widget/Index.jsx index 687c0930..a45c02c4 100644 --- a/apps/potlock/widget/Index.jsx +++ b/apps/potlock/widget/Index.jsx @@ -1,6 +1,4 @@ const ownerId = "potlock.near"; -const registryContractId = - props.env === "staging" ? "registry.staging.potlock.near" : "registry.potlock.near"; const donationContractId = "donate.potlock.near"; const potFactoryContractId = props.env === "staging" ? "potfactory.staging.potlock.near" : "v1.potfactory.potlock.near"; @@ -66,10 +64,7 @@ State.init({ nearToUsd: null, isCartModalOpen: false, isNavMenuOpen: false, - registryConfig: null, - userIsRegistryAdmin: null, allPots: null, - registeredProjects: null, donnorProjectId: null, amount: null, note: null, @@ -137,11 +132,7 @@ if (!state.allPots) { }); } -if (!state.registeredProjects) { - State.update({ registeredProjects: Near.view(registryContractId, "get_projects", {}) }); -} - -if (!state.registeredProjects || !state.allPots) return ""; +if (!state.allPots) return ""; if (!state.donations) { State.update({ @@ -159,58 +150,6 @@ const getImageUrlFromSocialImage = (image) => { } }; -if (!state.registeredProjects) { - Near.asyncView(registryContractId, "get_projects", {}) - .then((projects) => { - // get social data for each project - Near.asyncView("social.near", "get", { - keys: projects.map((project) => `${project.id}/profile/**`), - }).then((socialData) => { - const formattedProjects = projects.map((project) => { - const profileData = socialData[project.id]?.profile; - let profileImageUrl = DEFAULT_PROFILE_IMAGE_URL; - if (profileData.image) { - const imageUrl = getImageUrlFromSocialImage(profileData.image); - if (imageUrl) profileImageUrl = imageUrl; - } - // get banner image URL - let bannerImageUrl = DEFAULT_BANNER_IMAGE_URL; - if (profileData.backgroundImage) { - const imageUrl = getImageUrlFromSocialImage(profileData.backgroundImage); - if (imageUrl) bannerImageUrl = imageUrl; - } - const formatted = { - id: project.id, - name: profileData.name ?? "", - description: profileData.description ?? "", - bannerImageUrl, - profileImageUrl, - status: project.status, - tags: [profileData.category.text ?? CATEGORY_MAPPINGS[profileData.category] ?? ""], - }; - return formatted; - }); - State.update({ - registeredProjects: formattedProjects, - }); - }); - }) - .catch((e) => { - console.log("error getting projects: ", e); - State.update({ getRegisteredProjectsError: e }); - }); -} - -if (state.registryConfig === null) { - const registryConfig = Near.view(registryContractId, "get_config", {}); - if (registryConfig) { - State.update({ - registryConfig, - userIsRegistryAdmin: registryConfig.admins.includes(context.accountId), - }); - } -} - const tabContentWidget = { [CREATE_PROJECT_TAB]: "Project.Create", [EDIT_PROJECT_TAB]: "Project.Create", @@ -366,7 +305,6 @@ const props = { }, }, DONATION_CONTRACT_ID: donationContractId, - REGISTRY_CONTRACT_ID: registryContractId, POT_FACTORY_CONTRACT_ID: potFactoryContractId, NADABOT_CONTRACT_ID: nadabotContractId, NADABOT_HUMAN_METHOD: "is_human", @@ -610,7 +548,7 @@ const Content = styled.div` const isForm = [CREATE_PROJECT_TAB].includes(props.tab); -if (!state.cart || !state.registeredProjects) { +if (!state.cart) { return ""; } diff --git a/apps/potlock/widget/Pots/ConfigForm.jsx b/apps/potlock/widget/Pots/ConfigForm.jsx index 090c6344..0920b9d3 100644 --- a/apps/potlock/widget/Pots/ConfigForm.jsx +++ b/apps/potlock/widget/Pots/ConfigForm.jsx @@ -2,7 +2,6 @@ const { ownerId, potDetail, potId, - REGISTRY_CONTRACT_ID, POT_FACTORY_CONTRACT_ID, NADABOT_CONTRACT_ID, NADABOT_HUMAN_METHOD, @@ -12,7 +11,10 @@ const { // console.log("props in config form: ", props); -const DEFAULT_REGISTRY_PROVIDER = `${REGISTRY_CONTRACT_ID}:is_registered`; +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + +const DEFAULT_REGISTRY_PROVIDER = `${registry.getContractId()}:is_registered`; const DEFAULT_SYBIL_WRAPPER_PROVIDER = `${NADABOT_CONTRACT_ID}:${NADABOT_HUMAN_METHOD}`; const DEFAULT_PROTOCOL_CONFIG_PROVIDER = `${POT_FACTORY_CONTRACT_ID}:get_protocol_config`; const CURRENT_SOURCE_CODE_VERSION = "0.1.0"; diff --git a/apps/potlock/widget/Profile/Body.jsx b/apps/potlock/widget/Profile/Body.jsx index 522f6f18..987285d1 100644 --- a/apps/potlock/widget/Profile/Body.jsx +++ b/apps/potlock/widget/Profile/Body.jsx @@ -1,7 +1,6 @@ const { ownerId, projectId, - REGISTRY_CONTRACT_ID, userIsRegistryAdmin, SUPPORTED_FTS: { NEAR }, getTagsFromSocialProfileData, @@ -11,19 +10,11 @@ const accountId = props.accountId ?? context.accountId; const [statusReview, setStatusReview] = useState({ modalOpen: false, notes: "", newStatus: "" }); +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + const handleUpdateStatus = () => { - Near.call([ - { - contractName: REGISTRY_CONTRACT_ID, - methodName: "admin_set_project_status", - args: { - project_id: projectId, - status: statusReview.newStatus, - review_notes: statusReview.notes, - }, - deposit: NEAR.toIndivisible(0.01).toString(), - }, - ]); + registry.setProjectStatus(projectId, statusReview.newStatus, statusReview.notes); }; const Wrapper = styled.div` diff --git a/apps/potlock/widget/Project/Actions.jsx b/apps/potlock/widget/Project/Actions.jsx index 0df328f4..5cbf4941 100644 --- a/apps/potlock/widget/Project/Actions.jsx +++ b/apps/potlock/widget/Project/Actions.jsx @@ -1,11 +1,12 @@ const [isModalDonationOpen, setIsModalDonationOpen] = useState(false); const [isModalDonationSucessOpen, setIsModalDonationSucessOpen] = useState(false); -const { ownerId, registeredProjects, projectId } = props; +const { ownerId, projectId } = props; -const projectIsApproved = useMemo(() => { - return registeredProjects.some((p) => p.id === projectId && p.status === "Approved"); -}, [registeredProjects, projectId]); +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + +const projectIsApproved = registry.isProjectApproved(projectId); const Container = styled.div` display: flex; diff --git a/apps/potlock/widget/Project/CreateForm.jsx b/apps/potlock/widget/Project/CreateForm.jsx index 87d92caf..9b402e46 100644 --- a/apps/potlock/widget/Project/CreateForm.jsx +++ b/apps/potlock/widget/Project/CreateForm.jsx @@ -1,6 +1,5 @@ const { ownerId, - REGISTRY_CONTRACT_ID, validateNearAddress, validateEVMAddress, validateGithubRepoUrl, @@ -41,7 +40,10 @@ const existingHorizonProject = Near.view(HORIZON_CONTRACT_ID, "get_project", { account_id: context.accountId, }); -const projects = Near.view(REGISTRY_CONTRACT_ID, "get_projects", {}); +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + +const projects = registry.getProjects() || []; const imageHeightPx = 120; const profileImageTranslateYPx = 220; @@ -322,8 +324,6 @@ State.init({ githubError: "", socialDataFetched: false, socialDataIsFetching: false, - registeredProjects: null, - getRegisteredProjectsError: "", isMultiAccountModalOpen: false, teamMember: "", teamMembers: [], @@ -531,17 +531,6 @@ useEffect(() => { } }, [state.socialDataFetched, state.isDao, state.daoAddress, context.accountId]); -if (context.accountId && !state.registeredProjects) { - Near.asyncView(REGISTRY_CONTRACT_ID, "get_projects", {}) - .then((projects) => { - State.update({ registeredProjects: projects }); - }) - .catch((e) => { - console.log("error getting projects: ", e); - State.update({ getRegisteredProjectsError: e }); - }); -} - const isCreateProjectDisabled = state.daoAddressError || !state.name || @@ -709,7 +698,7 @@ const handleCreateOrUpdateProject = (e) => { transactions.push( // register project on potlock { - contractName: REGISTRY_CONTRACT_ID, + contractName: registry.getContractId(), methodName: "register", deposit: Big(0.05).mul(Big(10).pow(24)), args: potlockRegistryArgs, @@ -766,7 +755,8 @@ const handleCreateOrUpdateProject = (e) => { const pollIntervalMs = 1000; // const totalPollTimeMs = 60000; // consider adding in to make sure interval doesn't run indefinitely const pollId = setInterval(() => { - Near.asyncView(REGISTRY_CONTRACT_ID, "get_project_by_id", { + // This is an async request, not converting to SDK yet + Near.asyncView(registry.getContractId(), "get_project_by_id", { project_id: context.accountId, // TODO: implement pagination (should be OK without until there are 500+ donations from this user) }).then((_project) => { @@ -791,12 +781,8 @@ if (props.projectId) { } const registeredProject = useMemo(() => { - return state.registeredProjects - ? state.registeredProjects?.find( - (project) => project.id == (state.isDao ? state.daoAddress : context.accountId) - ) - : null; -}, [state.registeredProjects, state.isDao, state.daoAddress]); + return registry.getProjectById(state.isDao ? state.daoAddress : context.accountId); +}, [state.isDao, state.daoAddress]); // console.log("registeredProject: ", registeredProject); @@ -810,7 +796,7 @@ const proposalInProgress = useMemo(() => { return proposals?.find((proposal) => { return ( proposal.status == "InProgress" && - proposal.kind.FunctionCall?.receiver_id == REGISTRY_CONTRACT_ID && + proposal.kind.FunctionCall?.receiver_id == registry.getContractId() && proposal.kind.FunctionCall?.actions[0]?.method_name == "register" ); }); diff --git a/apps/potlock/widget/Project/Detail.jsx b/apps/potlock/widget/Project/Detail.jsx index 80d93da5..a6ac6299 100644 --- a/apps/potlock/widget/Project/Detail.jsx +++ b/apps/potlock/widget/Project/Detail.jsx @@ -2,7 +2,6 @@ const { ownerId, projectId, userIsRegistryAdmin, - REGISTRY_CONTRACT_ID, tab, POT_FACTORY_CONTRACT_ID, DONATION_CONTRACT_ID, @@ -10,7 +9,10 @@ const { const { ProjectOptions } = VM.require(`${ownerId}/widget/Project.Options`); -const project = Near.view(REGISTRY_CONTRACT_ID, "get_project_by_id", { project_id: projectId }); +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + +const project = registry.getProjectById(projectId); if (!project || project == null) { return "Loading"; diff --git a/apps/potlock/widget/Project/ListPage.jsx b/apps/potlock/widget/Project/ListPage.jsx index fe68332b..4629ceb3 100644 --- a/apps/potlock/widget/Project/ListPage.jsx +++ b/apps/potlock/widget/Project/ListPage.jsx @@ -286,13 +286,14 @@ const donateRandomly = () => { }); }; -const projects = useMemo( - () => - userIsRegistryAdmin - ? props.registeredProjects - : props.registeredProjects.filter((project) => project.status === "Approved"), - [props.registeredProjects, userIsRegistryAdmin] -); +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + +const projects = registry.getProjects() || []; + +if (!registry.isRegistryAdmin(context.accountId)) { + projects = projects.filter((project) => project.status === "Approved"); +} const [totalDonations, totalDonors] = useMemo(() => { if (!props.donations) { diff --git a/apps/potlock/widget/Project/ModalDonation.jsx b/apps/potlock/widget/Project/ModalDonation.jsx index 894dffdd..dc2fe1c1 100644 --- a/apps/potlock/widget/Project/ModalDonation.jsx +++ b/apps/potlock/widget/Project/ModalDonation.jsx @@ -1,6 +1,5 @@ const { ownerId, - registeredProjects, allPots, recipientId, // TODO: change this to projectId referrerId, @@ -16,7 +15,10 @@ const { console.log("props in donation modal: ", props); -const projects = registeredProjects || []; +const PotlockRegistrySDK = VM.require("potlock.near/widget/SDK.registry"); +const registry = PotlockRegistrySDK({ env: props.env }); + +const projects = registry.getProjects() || []; const approvedProjectIds = useMemo( // TODO: get projects for pot if potId diff --git a/apps/potlock/widget/SDK/registry.jsx b/apps/potlock/widget/SDK/registry.jsx new file mode 100644 index 00000000..810e6b16 --- /dev/null +++ b/apps/potlock/widget/SDK/registry.jsx @@ -0,0 +1,39 @@ +return ({ env }) => { + const contractId = env === "staging" ? "registry.staging.potlock.near" : "registry.potlock.near"; + + const PotlockRegistrySDK = { + getContractId: () => contractId, + getConfig: () => { + return Near.view(contractId, "get_config", {}); + }, + isRegistryAdmin: (accountId) => { + const config = PotlockRegistrySDK.getConfig(); + return config.admins && config.admins.includes(accountId); + }, + setProjectStatus: (projectId, status, reviewNotes) => { + return Near.call([ + { + contractName: contractId, + methodName: "admin_set_project_status", + args: { + project_id: projectId, + status, + review_notes: reviewNotes, + }, + deposit: NEAR.toIndivisible(0.01).toString(), + }, + ]); + }, + getProjects: () => { + return Near.view(contractId, "get_projects", {}); + }, + getProjectById: (projectId) => { + return Near.view(contractId, "get_project_by_id", { project_id: projectId }); + }, + isProjectApproved: (projectId) => { + const project = PotlockRegistrySDK.getProjectById(projectId); + return project && project.status === "Approved"; + }, + }; + return PotlockRegistrySDK; +};