Skip to content

Commit

Permalink
Offchain Debates can be created now
Browse files Browse the repository at this point in the history
  • Loading branch information
ashutoshpw committed Jan 14, 2025
1 parent 6a8d836 commit 7bc9dd8
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 55 deletions.
4 changes: 3 additions & 1 deletion src/modules/etherlink/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export const EvmProposalOptions = [
label: "Off-Chain Debate",
description: "Post a thesis and have tokenized arguments around it",
modal: "off_chain_debate",
is_disabled: true
proposal_type: () => "off_chain_debate",
last_step: 2,
interface: {}
},
{
label: "Transfer Assets",
Expand Down
31 changes: 13 additions & 18 deletions src/modules/etherlink/explorer/EvmProposals/EvmOffchainDebate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from "react"
import { Grid, styled, Typography, IconButton, FormControlLabel, Switch } from "@material-ui/core"
import { Add as AddIcon, RemoveCircleOutline } from "@material-ui/icons"
import { StyledTextField } from "components/ui/StyledTextField"
import { useEvmProposalOps } from "services/contracts/etherlinkDAO/hooks/useEvmProposalOps"

const InputContainer = styled(Grid)({
background: "#1c2024",
Expand All @@ -27,20 +28,14 @@ const RemoveButton = styled(IconButton)({
})

export const EvmOffchainDebate: React.FC = () => {
const [duration, setDuration] = useState({
days: "",
hours: "",
minutes: ""
})

const [choices, setChoices] = useState<string[]>(["", ""])
const [isMultiChoice, setIsMultiChoice] = useState(false)
const { offchainDebate, setOffchainDebate } = useEvmProposalOps()
const choices = offchainDebate?.options
const setChoices = (x: any) => setOffchainDebate("options", x)
const isMultiChoice = offchainDebate?.is_multiple_choice
const setIsMultiChoice = (x: any) => setOffchainDebate("is_multiple_choice", x)

const handleDurationChange = (field: string, value: string) => {
setDuration(prev => ({
...prev,
[field]: value
}))
setOffchainDebate(field, value)
}

const handleChoiceChange = (index: number, value: string) => {
Expand Down Expand Up @@ -72,8 +67,8 @@ export const EvmOffchainDebate: React.FC = () => {
fullWidth
label="Days"
type="number"
value={duration.days}
onChange={e => handleDurationChange("days", e.target.value)}
value={offchainDebate.expiry_days}
onChange={e => handleDurationChange("expiry_days", e.target.value)}
inputProps={{ min: 0 }}
/>
</Grid>
Expand All @@ -82,8 +77,8 @@ export const EvmOffchainDebate: React.FC = () => {
fullWidth
label="Hours"
type="number"
value={duration.hours}
onChange={e => handleDurationChange("hours", e.target.value)}
value={offchainDebate.expiry_hours}
onChange={e => handleDurationChange("expiry_hours", e.target.value)}
inputProps={{ min: 0, max: 23 }}
/>
</Grid>
Expand All @@ -92,8 +87,8 @@ export const EvmOffchainDebate: React.FC = () => {
fullWidth
label="Minutes"
type="number"
value={duration.minutes}
onChange={e => handleDurationChange("minutes", e.target.value)}
value={offchainDebate.expiry_minutes}
onChange={e => handleDurationChange("expiry_minutes", e.target.value)}
inputProps={{ min: 0, max: 59 }}
/>
</Grid>
Expand Down
6 changes: 3 additions & 3 deletions src/modules/etherlink/explorer/EvmProposalsActionDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ export const EvmProposalsActionDialog = ({ open, handleClose }: { open: boolean;
<Typography color="textPrimary">Select Proposal Type</Typography>
</TitleContainer>
<Grid container spacing={2}>
{EvmProposalOptions.map((option, index) => (
{EvmProposalOptions.map((option: any, index) => (
<Grid
item
xs={isMobileSmall ? 12 : 4}
key={index}
onClick={() => setMetadataFieldValue("type", option.modal as any)}
>
<OptionContainer>
<ActionText color={option.is_disabled ? "textSecondary" : "textPrimary"}>{option.label}</ActionText>
<ActionDescriptionText color={option.is_disabled ? "textSecondary" : "textPrimary"}>
<ActionText color={option?.is_disabled ? "textSecondary" : "textPrimary"}>{option.label}</ActionText>
<ActionDescriptionText color={option?.is_disabled ? "textSecondary" : "textPrimary"}>
{option.description}
</ActionDescriptionText>
</OptionContainer>
Expand Down
16 changes: 11 additions & 5 deletions src/modules/etherlink/explorer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ import { EtherlinkContext } from "services/wagmi/context"
import { EvmDaoStatsRow } from "../components/EvmDaoStatsRow"
import { EvmDaoSettingModal } from "../components/EvmDaoSettingsModal"
import { EvmTreasuryTable } from "../components/EvmTreasuryTable"
import { useEvmProposalOps } from "services/contracts/etherlinkDAO/hooks/useEvmProposalOps"
import { useHistory } from "react-router-dom"

export const EtherlinkDAOOverview: React.FC = () => {
const { daoSelected } = useContext(EtherlinkContext)

const theme = useTheme()
const isExtraSmall = useMediaQuery(theme.breakpoints.down("xs"))
const { setMetadataFieldValue, setCurrentStep } = useEvmProposalOps()
const history = useHistory()

const name = daoSelected && daoSelected?.name
const description = daoSelected && daoSelected?.description
Expand All @@ -31,10 +35,6 @@ export const EtherlinkDAOOverview: React.FC = () => {
setOpenDialog(false)
}

const handleCloseChangeModal = () => {
setChangeOpenDialog(false)
}

return (
<Grid container direction="column" style={{ gap: isExtraSmall ? 25 : 32 }}>
<HeroContainer item>
Expand All @@ -54,7 +54,13 @@ export const EtherlinkDAOOverview: React.FC = () => {
<EvmDaoSettingModal open={openDialog} handleClose={handleCloseModal} />
</Grid>
<Grid item>
<SmallButton onClick={() => setChangeOpenDialog(true)}>
<SmallButton
onClick={() => {
setMetadataFieldValue("type", "change_config")
setCurrentStep(1)
history.push(`${window.location.pathname.slice(0, -8)}proposals`)
}}
>
<Typography color="primary">Change Settings</Typography>
</SmallButton>
{/* <SettingsDialog open={openChangeDialog} handleClose={handleCloseChangeModal} /> */}
Expand Down
136 changes: 108 additions & 28 deletions src/services/contracts/etherlinkDAO/hooks/useEvmProposalOps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import HbDaoAbi from "assets/abis/hb_dao.json"
import { useNotification } from "modules/common/hooks/useNotification"
import { EvmProposalOptions, proposalInterfaces } from "modules/etherlink/config"
import { useHistory } from "react-router-dom"
import dayjs from "dayjs"
import { getSignature } from "services/lite/utils"
import { getEthSignature } from "services/utils/utils"
import { saveLiteProposal } from "services/services/lite/lite-services"

function getDaoConfigType(type: string) {
if (type === "quorumNumerator") return "quorum"
Expand Down Expand Up @@ -87,6 +91,14 @@ interface EvmProposalCreateStore {
}
}
setDaoTokenOps: (type: "mint" | "burn", value?: any, tokenSymbol?: string, tokenAddress?: string) => void
offchainDebate: {
expiry_days: string
expiry_hours: string
expiry_minutes: string
options: string[]
is_multiple_choice: boolean
}
setOffchainDebate: (key: string, value: string) => void
getMetadata: () => EvmProposalCreateStore["metadata"]
setMetadata: (metadata: EvmProposalCreateStore["metadata"]) => void
getMetadataFieldValue: (field: keyof EvmProposalCreateStore["metadata"]) => string
Expand Down Expand Up @@ -336,6 +348,17 @@ const useEvmProposalCreateZustantStore = create<EvmProposalCreateStore>()(
}
set(payload)
},
offchainDebate: {
expiry_days: "",
expiry_hours: "",
expiry_minutes: "",
options: ["", ""],
is_multiple_choice: false
},
setOffchainDebate: (key: string, value: string) => {
const payload = { offchainDebate: { ...get().offchainDebate, [key]: value } } as any
set(payload)
},
getMetadata: () => {
return get().metadata
},
Expand Down Expand Up @@ -374,7 +397,7 @@ const useEvmProposalCreateZustantStore = create<EvmProposalCreateStore>()(

export const useEvmProposalOps = () => {
const [isLoading, setIsLoading] = useState(false)
const { etherlink } = useTezos()
const { etherlink, network } = useTezos()
const { daoSelected, daoProposalSelected } = useContext(EtherlinkContext)
const router = useHistory()

Expand Down Expand Up @@ -480,7 +503,7 @@ export const useEvmProposalOps = () => {

const nextStep = {
text: isLoading ? "Please wait..." : "Next",
handler: () => {
handler: async () => {
// const selectedInterface = proposalInterfaces.find(p => p.name === "transferETH")
// if (!selectedInterface) return
// console.log("selectedInterface", selectedInterface)
Expand Down Expand Up @@ -525,42 +548,99 @@ export const useEvmProposalOps = () => {
// At Step 2 we call the Contract
// setIsLoading(true)

console.log("zustantStore.createProposalPayload", zustantStore.createProposalPayload)
const { closeSnackbar } = openNotification({
message: "Creating Proposal...",
variant: "success"
})

createProposal(zustantStore.createProposalPayload)
.then((createdProposal: any) => {
console.log("createdProposal", createdProposal)
setIsLoading(false)
zustantStore.setCurrentStep(0)
zustantStore.setCreateProposalPayload({
targets: [],
values: [],
calldatas: [],
description: ""
if (proposalType === "off_chain_debate") {
const offchainPayload = zustantStore.offchainDebate
const proposalMetadata = zustantStore.metadata
const dataToSign = {
name: proposalMetadata.title,
description: proposalMetadata.description,
externalLink: proposalMetadata.discussionUrl,
choices: offchainPayload.options,
endTimeDays: offchainPayload.expiry_days,
endTimeHours: offchainPayload.expiry_hours,
endTimeMinutes: offchainPayload.expiry_minutes,
votingStrategy: offchainPayload.is_multiple_choice,
startTime: String(dayjs().valueOf()),
endTime: String(
dayjs()
.add(Number(offchainPayload.expiry_days), "days")
.add(Number(offchainPayload.expiry_hours), "hours")
.add(Number(offchainPayload.expiry_minutes), "minutes")
.valueOf()
),
daoId: daoSelected?.address,
tokenAddress: daoSelected?.token,
author: etherlink?.signer?.address
}
const { signature, payloadBytes } = await getEthSignature(
etherlink?.signer?.address as string,
JSON.stringify(dataToSign)
)
if (!signature) {
openNotification({
message: `Issue with Signature`,
autoHideDuration: 3000,
variant: "error"
})
zustantStore.setMetadata({
type: "",
title: "",
description: "",
discussionUrl: ""
return
}
const res = await saveLiteProposal(signature, etherlink?.signer?.address, payloadBytes, network)
const respData = await res.json()
if (res.ok) {
openNotification({
message: "Proposal created!",
autoHideDuration: 3000,
variant: "success"
})
router.push(`/explorer/etherlink/dao/${daoSelected?.address}/proposals`)
})
.catch(err => {
console.log("Error creating proposal", err)
} else {
console.log("Error: ", respData.message)
openNotification({
message: `Error creating proposal: ${err.message}`,
variant: "error",
autoHideDuration: 3000
message: respData.message,
autoHideDuration: 3000,
variant: "error"
})
})
.finally(() => {
closeSnackbar()
})
setIsLoading(false)
return
}
return console.log("offchainDebate", offchainPayload, proposalMetadata, signature, payloadBytes)
} else {
createProposal(zustantStore.createProposalPayload)
.then((createdProposal: any) => {
console.log("createdProposal", createdProposal)
setIsLoading(false)
zustantStore.setCurrentStep(0)
zustantStore.setCreateProposalPayload({
targets: [],
values: [],
calldatas: [],
description: ""
})
zustantStore.setMetadata({
type: "",
title: "",
description: "",
discussionUrl: ""
})
router.push(`/explorer/etherlink/dao/${daoSelected?.address}/proposals`)
})
.catch(err => {
console.log("Error creating proposal", err)
openNotification({
message: `Error creating proposal: ${err.message}`,
variant: "error",
autoHideDuration: 3000
})
})
.finally(() => {
closeSnackbar()
})
}
}
}
}
Expand Down

0 comments on commit 7bc9dd8

Please sign in to comment.