From 49159e9de0cd37c9d29664a44498b88d24c9ada6 Mon Sep 17 00:00:00 2001 From: Kellar Date: Thu, 11 Apr 2024 14:19:42 +0100 Subject: [PATCH 01/22] Remove max length on snapshotURL input --- src/components/DaoCreator/formComponents/EstablishEssentials.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx index 89de33253d..7242ecbf20 100644 --- a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx +++ b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx @@ -167,7 +167,6 @@ export function EstablishEssentials(props: ICreationStepProps) { isDisabled={snapshotURLDisabled} data-testid="essentials-snapshotURL" placeholder="example.eth" - maxLength={30} /> From 5375892c75f43f9470d7bc8cfa93235b71131a04 Mon Sep 17 00:00:00 2001 From: Kellar Date: Mon, 15 Apr 2024 19:49:42 +0100 Subject: [PATCH 02/22] Have snapshot spaces only load from prod env --- src/hooks/DAO/loaders/snapshot/index.ts | 5 ++--- src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts | 7 +------ src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts | 7 +------ 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/hooks/DAO/loaders/snapshot/index.ts b/src/hooks/DAO/loaders/snapshot/index.ts index 4c6c14b179..a458f7db38 100644 --- a/src/hooks/DAO/loaders/snapshot/index.ts +++ b/src/hooks/DAO/loaders/snapshot/index.ts @@ -11,9 +11,8 @@ const defaultOptions: DefaultOptions = { }, }; -export const createClient = (uri: string) => - new ApolloClient({ - uri: `https://${uri.includes('testnet') ? 'testnet.' : ''}hub.snapshot.org/graphql`, +export const createClient = () => new ApolloClient({ + uri: 'https://hub.snapshot.org/graphql', cache: new InMemoryCache(), defaultOptions, }); diff --git a/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts b/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts index 24ea78a238..adb96e3aed 100644 --- a/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts +++ b/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts @@ -17,17 +17,12 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u const [extendedSnapshotProposal, setExtendedSnapshotProposal] = useState(); const { - node: { daoSnapshotURL }, readOnly: { user: { address }, }, } = useFractal(); const daoSnapshotSpaceName = useSnapshotSpaceName(); - const client = useMemo(() => { - if (daoSnapshotURL) { - return createClient(daoSnapshotURL); - } - }, [daoSnapshotURL]); + const client = useMemo(() => createClient(), []); const snapshotProposal = proposal as SnapshotProposal; const isSnapshotProposal = useMemo( diff --git a/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts b/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts index 3156b53459..722f380dd7 100644 --- a/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts +++ b/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts @@ -9,16 +9,11 @@ import { createClient } from './'; export const useSnapshotProposals = () => { const { - node: { daoSnapshotURL }, action, } = useFractal(); const daoSnapshotSpaceName = useSnapshotSpaceName(); const currentSnapshotURL = useRef(); - const client = useMemo(() => { - if (daoSnapshotURL) { - return createClient(daoSnapshotURL); - } - }, [daoSnapshotURL]); + const client = useMemo(() => createClient(), []); const loadSnapshotProposals = useCallback(async () => { if (client) { From 281283a1a2506071de9c8c1ec4d2416848a31c21 Mon Sep 17 00:00:00 2001 From: Kellar Date: Mon, 15 Apr 2024 20:15:50 +0100 Subject: [PATCH 03/22] Fix broken snapshot link --- src/components/ui/badges/Snapshot.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ui/badges/Snapshot.tsx b/src/components/ui/badges/Snapshot.tsx index a871ee970c..cb9bc6a928 100644 --- a/src/components/ui/badges/Snapshot.tsx +++ b/src/components/ui/badges/Snapshot.tsx @@ -6,9 +6,10 @@ interface Props extends ButtonProps { } export default function Snapshot({ snapshotURL, mt }: Props) { + const url = snapshotURL.includes('testnet') ? snapshotURL : `https://snapshot.org/#${snapshotURL}`; return ( @@ -193,7 +193,7 @@ export default function MetadataContainer() { )} - {node.daoSnapshotURL && } + {node.daoSnapshotENS && } ); diff --git a/src/hooks/DAO/loaders/useFractalNode.ts b/src/hooks/DAO/loaders/useFractalNode.ts index 6d006ddf1c..e4458612a7 100644 --- a/src/hooks/DAO/loaders/useFractalNode.ts +++ b/src/hooks/DAO/loaders/useFractalNode.ts @@ -49,7 +49,7 @@ export const useFractalNode = ( }, daoName: name as string, daoAddress: utils.getAddress(_daoAddress as string), - daoSnapshotURL: snapshotURL as string, + daoSnapshotENS: snapshotURL as string, proposalTemplatesHash: proposalTemplatesHash as string, }; return currentNode; diff --git a/src/hooks/DAO/loaders/useLoadDAONode.ts b/src/hooks/DAO/loaders/useLoadDAONode.ts index ba5c53d35d..cf4ecaff33 100644 --- a/src/hooks/DAO/loaders/useLoadDAONode.ts +++ b/src/hooks/DAO/loaders/useLoadDAONode.ts @@ -39,7 +39,7 @@ export const useLoadDAONode = () => { }, daoName: name as string, daoAddress: utils.getAddress(_daoAddress as string), - daoSnapshotURL: snapshotURL as string, + daoSnapshotENS: snapshotURL as string, }; return currentNode; } diff --git a/src/hooks/DAO/proposal/useCastVote.ts b/src/hooks/DAO/proposal/useCastVote.ts index f0550e5836..e235da84f6 100644 --- a/src/hooks/DAO/proposal/useCastVote.ts +++ b/src/hooks/DAO/proposal/useCastVote.ts @@ -34,7 +34,7 @@ const useCastVote = ({ const { governanceContracts: { ozLinearVotingContractAddress, erc721LinearVotingContractAddress }, governance, - node: { daoSnapshotURL }, + node: { daoSnapshotENS }, readOnly: { user: { address }, }, @@ -43,15 +43,15 @@ const useCastVote = ({ const daoSnapshotSpaceName = useSnapshotSpaceName(); const signer = useEthersSigner(); const client = useMemo(() => { - if (daoSnapshotURL) { - const isTestnetSnapshotURL = daoSnapshotURL.includes('testnet'); + if (daoSnapshotENS) { + const isTestnetSnapshotURL = daoSnapshotENS.includes('testnet'); const hub = isTestnetSnapshotURL ? 'https://testnet.seq.snapshot.org' // This is not covered in Snapshot docs, but that's where they're sending request on testnet : 'https://hub.snapshot.org'; return new snapshot.Client712(hub); } return undefined; - }, [daoSnapshotURL]); + }, [daoSnapshotENS]); const azoriusGovernance = useMemo(() => governance as AzoriusGovernance, [governance]); const { type } = azoriusGovernance; diff --git a/src/models/DaoTxBuilder.ts b/src/models/DaoTxBuilder.ts index ce6afa7069..1b64e2d568 100644 --- a/src/models/DaoTxBuilder.ts +++ b/src/models/DaoTxBuilder.ts @@ -85,7 +85,7 @@ export class DaoTxBuilder extends BaseTxBuilder { } if (shouldSetSnapshot) { - this.internalTxs = this.internalTxs.concat(this.buildUpdateDAOSnapshotURLTx()); + this.internalTxs = this.internalTxs.concat(this.buildUpdateDAOSnapshotENSTx()); } this.internalTxs = this.internalTxs.concat( @@ -159,7 +159,7 @@ export class DaoTxBuilder extends BaseTxBuilder { const multisigTxBuilder = this.txBuilderFactory.createMultiSigTxBuilder(); this.internalTxs.push(this.buildUpdateDAONameTx()); - this.internalTxs.push(this.buildUpdateDAOSnapshotURLTx()); + this.internalTxs.push(this.buildUpdateDAOSnapshotENSTx()); // subDAO case, add freeze guard if (this.parentAddress) { @@ -227,7 +227,7 @@ export class DaoTxBuilder extends BaseTxBuilder { ); } - private buildUpdateDAOSnapshotURLTx(): SafeTransaction { + private buildUpdateDAOSnapshotENSTx(): SafeTransaction { return buildContractCall( this.baseContracts.keyValuePairsContract, 'updateValues', diff --git a/src/pages/daos/[daoAddress]/edit/governance/index.tsx b/src/pages/daos/[daoAddress]/edit/governance/index.tsx index 174fc56ae1..0a1a7475ce 100644 --- a/src/pages/daos/[daoAddress]/edit/governance/index.tsx +++ b/src/pages/daos/[daoAddress]/edit/governance/index.tsx @@ -21,7 +21,7 @@ import { export default function ModifyGovernancePage() { const { - node: { daoAddress, safe, daoName, daoSnapshotURL }, + node: { daoAddress, safe, daoName, daoSnapshotENS }, governance: { type }, readOnly: { user }, } = useFractal(); @@ -36,7 +36,7 @@ export default function ModifyGovernancePage() { deployAzorius( daoData as AzoriusERC20DAO | AzoriusERC721DAO, !daoName || createAccountSubstring(daoAddress!) === daoName, - !daoSnapshotURL && !!daoData.snapshotURL, + !daoSnapshotENS && !!daoData.snapshotURL, ); }; diff --git a/src/types/fractal.ts b/src/types/fractal.ts index 8c0bc7b3b6..0aaf582bb9 100644 --- a/src/types/fractal.ts +++ b/src/types/fractal.ts @@ -238,7 +238,7 @@ export interface FractalNode { nodeHierarchy: NodeHierarchy; isModulesLoaded?: boolean; isHierarchyLoaded?: boolean; - daoSnapshotURL?: string; + daoSnapshotENS?: string; proposalTemplatesHash?: string; } From 30ee5b03bd081bab9e32f4ef7ba76b637e56b1e0 Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 16 Apr 2024 17:33:59 +0100 Subject: [PATCH 12/22] Don't attempt to split snapshot name in `useSnapshotSpaceName` --- src/hooks/DAO/loaders/snapshot/useSnapshotSpaceName.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/DAO/loaders/snapshot/useSnapshotSpaceName.ts b/src/hooks/DAO/loaders/snapshot/useSnapshotSpaceName.ts index 478930a086..d47fa442ef 100644 --- a/src/hooks/DAO/loaders/snapshot/useSnapshotSpaceName.ts +++ b/src/hooks/DAO/loaders/snapshot/useSnapshotSpaceName.ts @@ -2,8 +2,8 @@ import { useFractal } from '../../../../providers/App/AppProvider'; export default function useSnapshotSpaceName() { const { - node: { daoSnapshotURL }, + node: { daoSnapshotENS }, } = useFractal(); - return daoSnapshotURL?.split('/').pop(); + return daoSnapshotENS; } From b150213045113ff903ad0cb19bba37327d6f3b51 Mon Sep 17 00:00:00 2001 From: Kellar Date: Tue, 16 Apr 2024 17:35:31 +0100 Subject: [PATCH 13/22] Remove snapshot testnet checks reference in `useCastVote.ts`. Use prod URL only --- src/hooks/DAO/proposal/useCastVote.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/hooks/DAO/proposal/useCastVote.ts b/src/hooks/DAO/proposal/useCastVote.ts index e235da84f6..9a75f048b2 100644 --- a/src/hooks/DAO/proposal/useCastVote.ts +++ b/src/hooks/DAO/proposal/useCastVote.ts @@ -44,11 +44,7 @@ const useCastVote = ({ const signer = useEthersSigner(); const client = useMemo(() => { if (daoSnapshotENS) { - const isTestnetSnapshotURL = daoSnapshotENS.includes('testnet'); - const hub = isTestnetSnapshotURL - ? 'https://testnet.seq.snapshot.org' // This is not covered in Snapshot docs, but that's where they're sending request on testnet - : 'https://hub.snapshot.org'; - return new snapshot.Client712(hub); + return new snapshot.Client712('https://hub.snapshot.org'); } return undefined; }, [daoSnapshotENS]); From c2820972e2113403dd5b5be665eb244942df3c81 Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 17 Apr 2024 12:41:40 +0100 Subject: [PATCH 14/22] Rename remaining references to snapshotURL to snapshotENS; ensure compatibility with outside world's snapshotURL --- src/components/DaoCreator/constants.ts | 2 +- .../formComponents/EstablishEssentials.tsx | 14 +++++++------- src/components/DaoCreator/index.tsx | 12 +++++++++--- src/components/Proposals/ProposalInfo.tsx | 2 +- .../DaoSettings/components/Metadata/index.tsx | 8 ++++---- src/components/ui/badges/Snapshot.tsx | 6 +++--- src/components/ui/cards/DAOInfoCard.tsx | 2 +- .../DAO/loaders/snapshot/useSnapshotProposals.ts | 6 +++--- src/hooks/DAO/loaders/useFractalNode.ts | 10 ++++++++-- src/hooks/DAO/loaders/useLoadDAONode.ts | 4 ++-- .../schemas/DAOCreate/useDAOCreateSchema.ts | 2 +- src/types/createDAO.ts | 16 +++++++++++++--- src/types/fractal.ts | 4 ++-- 13 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/components/DaoCreator/constants.ts b/src/components/DaoCreator/constants.ts index 196ad440ed..d29a0f36a7 100644 --- a/src/components/DaoCreator/constants.ts +++ b/src/components/DaoCreator/constants.ts @@ -13,7 +13,7 @@ export const initialState: CreatorFormState = { essentials: { daoName: '', governance: GovernanceType.MULTISIG, - snapshotURL: '', + snapshotENS: '', }, erc20Token: { tokenCreationType: TokenCreationType.NEW, diff --git a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx index 0e40182ffa..48e255c8ed 100644 --- a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx +++ b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx @@ -43,7 +43,7 @@ export function EstablishEssentials(props: ICreationStepProps) { setFieldValue('essentials.daoName', daoName, false); if (createAccountSubstring(daoAddress!) !== daoName) { // Pre-fill the snapshot URL form field when editing - setFieldValue('essentials.snapshotURL', daoSnapshotENS || '', false); + setFieldValue('essentials.snapshotENS', daoSnapshotENS || '', false); } } }, [setFieldValue, mode, daoName, daoSnapshotENS, isEdit, daoAddress]); @@ -52,7 +52,7 @@ export function EstablishEssentials(props: ICreationStepProps) { isEdit && !!daoName && !!daoAddress && createAccountSubstring(daoAddress) !== daoName; // If in governance edit mode and snapshot URL is already set, disable the field - const snapshotURLDisabled = isEdit && !!daoSnapshotENS; + const snapshotENSDisabled = isEdit && !!daoSnapshotENS; const handleGovernanceChange = (value: string) => { if (value === GovernanceType.AZORIUS_ERC20) { @@ -65,7 +65,7 @@ export function EstablishEssentials(props: ICreationStepProps) { }; const handleSnapshotSpaceChange = (value: string) => { - setFieldValue('essentials.snapshotURL', value, true); + setFieldValue('essentials.snapshotENS', value, true); try { ens_normalize(value); setSnapshotSpaceValid(true); @@ -179,12 +179,12 @@ export function EstablishEssentials(props: ICreationStepProps) { helper={t('snapshotHelper')} isRequired={false} > - + handleSnapshotSpaceChange(cEvent.target.value)} - isDisabled={snapshotURLDisabled} - data-testid="essentials-snapshotURL" + isDisabled={snapshotENSDisabled} + data-testid="essentials-snapshotENS" placeholder="example.eth" /> diff --git a/src/components/DaoCreator/index.tsx b/src/components/DaoCreator/index.tsx index e4c3ce5980..e49f575cf7 100644 --- a/src/components/DaoCreator/index.tsx +++ b/src/components/DaoCreator/index.tsx @@ -29,10 +29,16 @@ function DaoCreator({ onSubmit={async values => { const choosenGovernance = values.essentials.governance; const freezeGuard = isSubDAO ? values.freeze : undefined; + + const valuesEssentialsWithSnapshotURL = { + ...values.essentials, + snapshotURL: values.essentials.snapshotENS, + }; + switch (choosenGovernance) { case GovernanceType.MULTISIG: { const data = await prepareMultisigFormData({ - ...values.essentials, + ...valuesEssentialsWithSnapshotURL, ...values.multisig, freezeGuard, }); @@ -43,7 +49,7 @@ function DaoCreator({ } case GovernanceType.AZORIUS_ERC20: { const data = await prepareAzoriusERC20FormData({ - ...values.essentials, + ...valuesEssentialsWithSnapshotURL, ...values.azorius, ...values.erc20Token, freezeGuard, @@ -55,7 +61,7 @@ function DaoCreator({ } case GovernanceType.AZORIUS_ERC721: { const data = await prepareAzoriusERC721FormData({ - ...values.essentials, + ...valuesEssentialsWithSnapshotURL, ...values.azorius, ...values.erc721Token, freezeGuard, diff --git a/src/components/Proposals/ProposalInfo.tsx b/src/components/Proposals/ProposalInfo.tsx index d36cef9a8a..4241c6eb4e 100644 --- a/src/components/Proposals/ProposalInfo.tsx +++ b/src/components/Proposals/ProposalInfo.tsx @@ -36,7 +36,7 @@ export function ProposalInfo({ {isSnapshotProposal && ( <> {(proposal as ExtendedSnapshotProposal).privacy === 'shutter' && ( diff --git a/src/components/pages/DaoSettings/components/Metadata/index.tsx b/src/components/pages/DaoSettings/components/Metadata/index.tsx index 2e574bf77f..831fc68078 100644 --- a/src/components/pages/DaoSettings/components/Metadata/index.tsx +++ b/src/components/pages/DaoSettings/components/Metadata/index.tsx @@ -41,7 +41,7 @@ export default function MetadataContainer() { } }, [daoName, daoSnapshotENS, daoAddress]); - const handleSnapshotURLChange: ChangeEventHandler = e => { + const handleSnapshotENSChange: ChangeEventHandler = e => { setSnapshotENS(e.target.value); try { ens_normalize(e.target.value); @@ -102,7 +102,7 @@ export default function MetadataContainer() { values: [0n], calldatas: [ keyValuePairsContract.asProvider.interface.encodeFunctionData('updateValues', [ - ['snapshotURL'], + ['snapshotENS'], [snapshotENS], ]), ], @@ -192,11 +192,11 @@ export default function MetadataContainer() { )} - {node.daoSnapshotENS && } + {node.daoSnapshotENS && } ); diff --git a/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts b/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts index cdfd12ae19..c2ae4e63f2 100644 --- a/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts +++ b/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts @@ -10,7 +10,7 @@ import { createClient } from './'; export const useSnapshotProposals = () => { const { action } = useFractal(); const daoSnapshotSpaceName = useSnapshotSpaceName(); - const currentSnapshotURL = useRef(); + const currentSnapshotENS = useRef(); const client = useMemo(() => createClient(), []); const loadSnapshotProposals = useCallback(async () => { @@ -76,8 +76,8 @@ export const useSnapshotProposals = () => { }, [action, daoSnapshotSpaceName, client]); useEffect(() => { - if (!daoSnapshotSpaceName || daoSnapshotSpaceName === currentSnapshotURL.current) return; - currentSnapshotURL.current = daoSnapshotSpaceName; + if (!daoSnapshotSpaceName || daoSnapshotSpaceName === currentSnapshotENS.current) return; + currentSnapshotENS.current = daoSnapshotSpaceName; loadSnapshotProposals(); }, [daoSnapshotSpaceName, loadSnapshotProposals]); }; diff --git a/src/hooks/DAO/loaders/useFractalNode.ts b/src/hooks/DAO/loaders/useFractalNode.ts index e4458612a7..ceb59f5086 100644 --- a/src/hooks/DAO/loaders/useFractalNode.ts +++ b/src/hooks/DAO/loaders/useFractalNode.ts @@ -40,7 +40,13 @@ export const useFractalNode = ( const { daos } = result.data; const dao = daos[0]; if (dao) { - const { parentAddress, name, hierarchy, snapshotURL, proposalTemplatesHash } = dao; + const { + parentAddress, + name, + hierarchy, + snapshotURL: snapshotENS, + proposalTemplatesHash, + } = dao; const currentNode: Node = { nodeHierarchy: { @@ -49,7 +55,7 @@ export const useFractalNode = ( }, daoName: name as string, daoAddress: utils.getAddress(_daoAddress as string), - daoSnapshotENS: snapshotURL as string, + daoSnapshotENS: snapshotENS as string, proposalTemplatesHash: proposalTemplatesHash as string, }; return currentNode; diff --git a/src/hooks/DAO/loaders/useLoadDAONode.ts b/src/hooks/DAO/loaders/useLoadDAONode.ts index cf4ecaff33..d20fceb44d 100644 --- a/src/hooks/DAO/loaders/useLoadDAONode.ts +++ b/src/hooks/DAO/loaders/useLoadDAONode.ts @@ -30,7 +30,7 @@ export const useLoadDAONode = () => { const { daos } = result.data; const dao = daos[0]; if (dao) { - const { parentAddress, name, hierarchy, snapshotURL } = dao; + const { parentAddress, name, hierarchy, snapshotURL: snapshotENS } = dao; const currentNode: Node = { nodeHierarchy: { @@ -39,7 +39,7 @@ export const useLoadDAONode = () => { }, daoName: name as string, daoAddress: utils.getAddress(_daoAddress as string), - daoSnapshotENS: snapshotURL as string, + daoSnapshotENS: snapshotENS as string, }; return currentNode; } diff --git a/src/hooks/schemas/DAOCreate/useDAOCreateSchema.ts b/src/hooks/schemas/DAOCreate/useDAOCreateSchema.ts index 934da55988..c2b83b0888 100644 --- a/src/hooks/schemas/DAOCreate/useDAOCreateSchema.ts +++ b/src/hooks/schemas/DAOCreate/useDAOCreateSchema.ts @@ -34,7 +34,7 @@ export const useDAOCreateSchema = ({ isSubDAO }: { isSubDAO?: boolean }) => { essentials: Yup.object().shape({ daoName: Yup.string().required(), governance: Yup.string().required(), - snapshotURL: Yup.string(), + snapshotENS: Yup.string(), }), multisig: Yup.object().when('essentials', { is: ({ governance }: DAOEssentials) => governance === GovernanceType.MULTISIG, diff --git a/src/types/createDAO.ts b/src/types/createDAO.ts index 21cbf986b7..44683e3fbf 100644 --- a/src/types/createDAO.ts +++ b/src/types/createDAO.ts @@ -38,9 +38,19 @@ export interface CreatorFormState { export type DAOEssentials = { daoName: string; governance: GovernanceType; - snapshotURL: string; + snapshotENS: string; }; +/** +* `DAOEssentialsEdge` is a transitionary type that is used in place of the in-app-only `DAOEssentials` type. +* `DAOEssentialsEdge` has a `snapshotURL` field in place of a `snapshotENS` field. +* +* A recent update necessitated the renaming of references to `snapshotURL` to `snapshotENS`, +* but as the contracts and subgraph already use `snapshotURL`, this type is used to maintain compatibility +* of the app with the contracts and subgraph of the outside world. +*/ +type DAOEssentialsEdge = Omit & { snapshotURL: string }; + export type DAOGovernorERC20Token = { tokenCreationType: TokenCreationType; tokenImportAddress?: string; @@ -90,7 +100,7 @@ export interface SubDAO DAOFreezeGuardConfig {} export interface AzoriusGovernanceDAO - extends DAOEssentials, + extends DAOEssentialsEdge, DAOGovernorModuleConfig {} export interface AzoriusERC20DAO @@ -104,7 +114,7 @@ export interface AzoriusERC721DAO extends AzoriusGovernanceDAO, DAOGovernorERC721Token {} -export interface SafeMultisigDAO extends DAOEssentials, SafeConfiguration {} +export interface SafeMultisigDAO extends DAOEssentialsEdge, SafeConfiguration {} export type DAOTrigger = ( daoData: SafeMultisigDAO | AzoriusERC20DAO | AzoriusERC721DAO | SubDAO, diff --git a/src/types/fractal.ts b/src/types/fractal.ts index 0aaf582bb9..9a984807b6 100644 --- a/src/types/fractal.ts +++ b/src/types/fractal.ts @@ -132,13 +132,13 @@ export enum FractalProposalState { /** * The proposal is pending, meaning it has been created, but voting has not yet begun. This state * has nothing to do with Fractal, and is used for Snapshot proposals only, which appear if the - * DAO's snapshotURL is set. + * DAO's snapshotENS is set. */ PENDING = 'statePending', /** * The proposal is closed, and no longer able to be signed. This state has nothing to do with Fractal, - * and is used for Snapshot proposals only, which appear if the DAO's snapshotURL is set. + * and is used for Snapshot proposals only, which appear if the DAO's snapshotENS is set. */ CLOSED = 'stateClosed', } From ed561a889b974f2b2804faaa8bcc5a98b7a95f4e Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 17 Apr 2024 12:44:00 +0100 Subject: [PATCH 15/22] Update snaphshotGraphQlClient name --- src/hooks/DAO/loaders/snapshot/index.ts | 2 +- .../loaders/snapshot/useSnapshotProposal.ts | 23 +++++++++++-------- .../loaders/snapshot/useSnapshotProposals.ts | 10 ++++---- src/types/createDAO.ts | 16 ++++++------- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/hooks/DAO/loaders/snapshot/index.ts b/src/hooks/DAO/loaders/snapshot/index.ts index 193bb2fd4d..1740bb2e90 100644 --- a/src/hooks/DAO/loaders/snapshot/index.ts +++ b/src/hooks/DAO/loaders/snapshot/index.ts @@ -11,7 +11,7 @@ const defaultOptions: DefaultOptions = { }, }; -export const createClient = () => +export const createSnapshotGraphQlClient = () => new ApolloClient({ uri: 'https://hub.snapshot.org/graphql', cache: new InMemoryCache(), diff --git a/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts b/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts index adb96e3aed..726524207e 100644 --- a/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts +++ b/src/hooks/DAO/loaders/snapshot/useSnapshotProposal.ts @@ -11,7 +11,7 @@ import { SnapshotWeightedVotingChoice, } from '../../../../types'; import useSnapshotSpaceName from './useSnapshotSpaceName'; -import { createClient } from './'; +import { createSnapshotGraphQlClient } from './'; export default function useSnapshotProposal(proposal: FractalProposal | null | undefined) { const [extendedSnapshotProposal, setExtendedSnapshotProposal] = @@ -22,7 +22,7 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u }, } = useFractal(); const daoSnapshotSpaceName = useSnapshotSpaceName(); - const client = useMemo(() => createClient(), []); + const snaphshotGraphQlClient = useMemo(() => createSnapshotGraphQlClient(), []); const snapshotProposal = proposal as SnapshotProposal; const isSnapshotProposal = useMemo( @@ -31,8 +31,8 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u ); const loadProposal = useCallback(async () => { - if (snapshotProposal?.snapshotProposalId && client) { - const proposalQueryResult = await client + if (snapshotProposal?.snapshotProposalId && snaphshotGraphQlClient) { + const proposalQueryResult = await snaphshotGraphQlClient .query({ query: gql` query ExtendedSnapshotProposal { @@ -72,7 +72,7 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u }, ); - const votesQueryResult = await client + const votesQueryResult = await snaphshotGraphQlClient .query({ query: gql`query SnapshotProposalVotes { votes(where: {proposal: "${snapshotProposal.snapshotProposalId}"}, first: 500) { @@ -194,7 +194,12 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u votes: votesQueryResult, } as ExtendedSnapshotProposal); } - }, [snapshotProposal?.snapshotProposalId, proposal, snapshotProposal?.state, client]); + }, [ + snapshotProposal?.snapshotProposalId, + proposal, + snapshotProposal?.state, + snaphshotGraphQlClient, + ]); const loadVotingWeight = useCallback(async () => { const emptyVotingWeight = { @@ -202,8 +207,8 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u votingWeightByStrategy: [0], votingState: '', }; - if (snapshotProposal?.snapshotProposalId && client) { - const queryResult = await client + if (snapshotProposal?.snapshotProposalId && snaphshotGraphQlClient) { + const queryResult = await snaphshotGraphQlClient .query({ query: gql` query UserVotingWeight { @@ -234,7 +239,7 @@ export default function useSnapshotProposal(proposal: FractalProposal | null | u } return emptyVotingWeight; - }, [address, snapshotProposal?.snapshotProposalId, client, daoSnapshotSpaceName]); + }, [address, snapshotProposal?.snapshotProposalId, snaphshotGraphQlClient, daoSnapshotSpaceName]); return { loadVotingWeight, diff --git a/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts b/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts index c2ae4e63f2..7bf8d495e9 100644 --- a/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts +++ b/src/hooks/DAO/loaders/snapshot/useSnapshotProposals.ts @@ -5,17 +5,17 @@ import { FractalGovernanceAction } from '../../../../providers/App/governance/ac import { ActivityEventType, FractalProposalState } from '../../../../types'; import { SnapshotProposal } from '../../../../types/daoProposal'; import useSnapshotSpaceName from './useSnapshotSpaceName'; -import { createClient } from './'; +import { createSnapshotGraphQlClient } from './'; export const useSnapshotProposals = () => { const { action } = useFractal(); const daoSnapshotSpaceName = useSnapshotSpaceName(); const currentSnapshotENS = useRef(); - const client = useMemo(() => createClient(), []); + const snaphshotGraphQlClient = useMemo(() => createSnapshotGraphQlClient(), []); const loadSnapshotProposals = useCallback(async () => { - if (client) { - client + if (snaphshotGraphQlClient) { + snaphshotGraphQlClient .query({ query: gql` query Proposals { @@ -73,7 +73,7 @@ export const useSnapshotProposals = () => { }); }); } - }, [action, daoSnapshotSpaceName, client]); + }, [action, daoSnapshotSpaceName, snaphshotGraphQlClient]); useEffect(() => { if (!daoSnapshotSpaceName || daoSnapshotSpaceName === currentSnapshotENS.current) return; diff --git a/src/types/createDAO.ts b/src/types/createDAO.ts index 44683e3fbf..9b5dd926c8 100644 --- a/src/types/createDAO.ts +++ b/src/types/createDAO.ts @@ -41,14 +41,14 @@ export type DAOEssentials = { snapshotENS: string; }; -/** -* `DAOEssentialsEdge` is a transitionary type that is used in place of the in-app-only `DAOEssentials` type. -* `DAOEssentialsEdge` has a `snapshotURL` field in place of a `snapshotENS` field. -* -* A recent update necessitated the renaming of references to `snapshotURL` to `snapshotENS`, -* but as the contracts and subgraph already use `snapshotURL`, this type is used to maintain compatibility -* of the app with the contracts and subgraph of the outside world. -*/ +/** + * `DAOEssentialsEdge` is a transitionary type that is used in place of the in-app-only `DAOEssentials` type. + * `DAOEssentialsEdge` has a `snapshotURL` field in place of a `snapshotENS` field. + * + * A recent update necessitated the renaming of references to `snapshotURL` to `snapshotENS`, + * but as the contracts and subgraph already use `snapshotURL`, this type is used to maintain compatibility + * of the app with the contracts and subgraph of the outside world. + */ type DAOEssentialsEdge = Omit & { snapshotURL: string }; export type DAOGovernorERC20Token = { From ff4f7dd2d1f6812d538f30eddf3b617df86bf9d4 Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 17 Apr 2024 12:50:23 +0100 Subject: [PATCH 16/22] Slight code style update --- .../DaoCreator/formComponents/EstablishEssentials.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx index 48e255c8ed..f10ea3a58d 100644 --- a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx +++ b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx @@ -66,13 +66,19 @@ export function EstablishEssentials(props: ICreationStepProps) { const handleSnapshotSpaceChange = (value: string) => { setFieldValue('essentials.snapshotENS', value, true); + + // If there's no input in the snapshot URL field, we don't need to check if it's valid + if (!value) { + setSnapshotSpaceValid(true); + return; + } + try { ens_normalize(value); setSnapshotSpaceValid(true); } catch (error) { console.log(error); - // If there's no input in the snapshot URL field, we don't need to check if it's valid - setSnapshotSpaceValid(!!value ? false : true); + setSnapshotSpaceValid(false); } }; From 42f2a5dd38d19b15dc32d4dd5b4e340598f785d3 Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 17 Apr 2024 12:51:05 +0100 Subject: [PATCH 17/22] isSnapshotSpaceValid should start out valid --- .../DaoCreator/formComponents/EstablishEssentials.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx index f10ea3a58d..b28dd61342 100644 --- a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx +++ b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx @@ -30,7 +30,7 @@ export function EstablishEssentials(props: ICreationStepProps) { const { t } = useTranslation(['daoCreate', 'common']); const { values, setFieldValue, isSubmitting, transactionPending, isSubDAO, errors, mode } = props; - const [isSnapshotSpaceValid, setSnapshotSpaceValid] = useState(false); + const [isSnapshotSpaceValid, setSnapshotSpaceValid] = useState(true); const { node: { daoName, daoSnapshotENS, daoAddress }, From d4af81425545da6c44079743a2b2c32e68fd97dc Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 17 Apr 2024 12:52:58 +0100 Subject: [PATCH 18/22] prettier --- .../DaoCreator/formComponents/EstablishEssentials.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx index b28dd61342..0349479ea5 100644 --- a/src/components/DaoCreator/formComponents/EstablishEssentials.tsx +++ b/src/components/DaoCreator/formComponents/EstablishEssentials.tsx @@ -68,10 +68,10 @@ export function EstablishEssentials(props: ICreationStepProps) { setFieldValue('essentials.snapshotENS', value, true); // If there's no input in the snapshot URL field, we don't need to check if it's valid - if (!value) { - setSnapshotSpaceValid(true); - return; - } + if (!value) { + setSnapshotSpaceValid(true); + return; + } try { ens_normalize(value); From deff8d60bf8a7dbaec942d8adabd74c8b6c22082 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 17 Apr 2024 09:03:03 -0400 Subject: [PATCH 19/22] Finish removing "snapshotURL" from the app everywhere except the edges --- src/components/DaoCreator/index.tsx | 11 +++-------- src/models/DaoTxBuilder.ts | 2 +- .../daos/[daoAddress]/edit/governance/index.tsx | 2 +- src/types/createDAO.ts | 14 ++------------ 4 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/components/DaoCreator/index.tsx b/src/components/DaoCreator/index.tsx index e49f575cf7..646cdd6eeb 100644 --- a/src/components/DaoCreator/index.tsx +++ b/src/components/DaoCreator/index.tsx @@ -30,15 +30,10 @@ function DaoCreator({ const choosenGovernance = values.essentials.governance; const freezeGuard = isSubDAO ? values.freeze : undefined; - const valuesEssentialsWithSnapshotURL = { - ...values.essentials, - snapshotURL: values.essentials.snapshotENS, - }; - switch (choosenGovernance) { case GovernanceType.MULTISIG: { const data = await prepareMultisigFormData({ - ...valuesEssentialsWithSnapshotURL, + ...values.essentials, ...values.multisig, freezeGuard, }); @@ -49,7 +44,7 @@ function DaoCreator({ } case GovernanceType.AZORIUS_ERC20: { const data = await prepareAzoriusERC20FormData({ - ...valuesEssentialsWithSnapshotURL, + ...values.essentials, ...values.azorius, ...values.erc20Token, freezeGuard, @@ -61,7 +56,7 @@ function DaoCreator({ } case GovernanceType.AZORIUS_ERC721: { const data = await prepareAzoriusERC721FormData({ - ...valuesEssentialsWithSnapshotURL, + ...values.essentials, ...values.azorius, ...values.erc721Token, freezeGuard, diff --git a/src/models/DaoTxBuilder.ts b/src/models/DaoTxBuilder.ts index 1b64e2d568..723b78b094 100644 --- a/src/models/DaoTxBuilder.ts +++ b/src/models/DaoTxBuilder.ts @@ -231,7 +231,7 @@ export class DaoTxBuilder extends BaseTxBuilder { return buildContractCall( this.baseContracts.keyValuePairsContract, 'updateValues', - [['snapshotURL'], [this.daoData.snapshotURL]], + [['snapshotURL'], [this.daoData.snapshotENS]], 0, false, ); diff --git a/src/pages/daos/[daoAddress]/edit/governance/index.tsx b/src/pages/daos/[daoAddress]/edit/governance/index.tsx index 0a1a7475ce..81d45f7550 100644 --- a/src/pages/daos/[daoAddress]/edit/governance/index.tsx +++ b/src/pages/daos/[daoAddress]/edit/governance/index.tsx @@ -36,7 +36,7 @@ export default function ModifyGovernancePage() { deployAzorius( daoData as AzoriusERC20DAO | AzoriusERC721DAO, !daoName || createAccountSubstring(daoAddress!) === daoName, - !daoSnapshotENS && !!daoData.snapshotURL, + !daoSnapshotENS && !!daoData.snapshotENS, ); }; diff --git a/src/types/createDAO.ts b/src/types/createDAO.ts index 9b5dd926c8..9d68f47b75 100644 --- a/src/types/createDAO.ts +++ b/src/types/createDAO.ts @@ -41,16 +41,6 @@ export type DAOEssentials = { snapshotENS: string; }; -/** - * `DAOEssentialsEdge` is a transitionary type that is used in place of the in-app-only `DAOEssentials` type. - * `DAOEssentialsEdge` has a `snapshotURL` field in place of a `snapshotENS` field. - * - * A recent update necessitated the renaming of references to `snapshotURL` to `snapshotENS`, - * but as the contracts and subgraph already use `snapshotURL`, this type is used to maintain compatibility - * of the app with the contracts and subgraph of the outside world. - */ -type DAOEssentialsEdge = Omit & { snapshotURL: string }; - export type DAOGovernorERC20Token = { tokenCreationType: TokenCreationType; tokenImportAddress?: string; @@ -100,7 +90,7 @@ export interface SubDAO DAOFreezeGuardConfig {} export interface AzoriusGovernanceDAO - extends DAOEssentialsEdge, + extends DAOEssentials, DAOGovernorModuleConfig {} export interface AzoriusERC20DAO @@ -114,7 +104,7 @@ export interface AzoriusERC721DAO extends AzoriusGovernanceDAO, DAOGovernorERC721Token {} -export interface SafeMultisigDAO extends DAOEssentialsEdge, SafeConfiguration {} +export interface SafeMultisigDAO extends DAOEssentials, SafeConfiguration {} export type DAOTrigger = ( daoData: SafeMultisigDAO | AzoriusERC20DAO | AzoriusERC721DAO | SubDAO, From 417356a6fbeb70df585e7785d0dcf7c7ff54ff83 Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 17 Apr 2024 16:42:44 +0100 Subject: [PATCH 20/22] Fix dao settings snapshot ens placeholder --- src/components/pages/DaoSettings/components/Metadata/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/pages/DaoSettings/components/Metadata/index.tsx b/src/components/pages/DaoSettings/components/Metadata/index.tsx index 831fc68078..a73f123d3d 100644 --- a/src/components/pages/DaoSettings/components/Metadata/index.tsx +++ b/src/components/pages/DaoSettings/components/Metadata/index.tsx @@ -195,7 +195,7 @@ export default function MetadataContainer() { onChange={handleSnapshotENSChange} value={snapshotENS} disabled={!userHasVotingWeight} - placeholder="httpsexample.eth" + placeholder="example.eth" testId="daoSettings.snapshotENS" gridContainerProps={{ display: 'inline-flex', From b513c9007b7f668c0695359e95e6b8d9af31563f Mon Sep 17 00:00:00 2001 From: Kellar Date: Wed, 17 Apr 2024 16:43:27 +0100 Subject: [PATCH 21/22] remove unused import --- src/components/ui/modals/ProposalTemplateModal.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ui/modals/ProposalTemplateModal.tsx b/src/components/ui/modals/ProposalTemplateModal.tsx index 6cc11a8431..71791f8631 100644 --- a/src/components/ui/modals/ProposalTemplateModal.tsx +++ b/src/components/ui/modals/ProposalTemplateModal.tsx @@ -8,7 +8,6 @@ import { Switch, VStack, } from '@chakra-ui/react'; -import { utils } from 'ethers'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; From 5ad1737e89a625a3a4f1b8bdb3a8282310af4c18 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Wed, 17 Apr 2024 19:00:02 -0400 Subject: [PATCH 22/22] 2024-04-17 release