Skip to content

Commit

Permalink
Update across the board ownership changes, url updates (#26)
Browse files Browse the repository at this point in the history
Fix URL changes, ownership updates.

Allow appending delete add operations for users to the current transaction queue.
  • Loading branch information
iainnash authored Jun 21, 2024
1 parent 2b0a1a8 commit 938bde8
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 55 deletions.
46 changes: 28 additions & 18 deletions src/app/NewSafeProposal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Field, FieldArray, Formik } from "formik";
import { SafeInformation } from "../components/SafeInformation";
import { Card, View, Text, Button, useToast } from "reshaped";
import { SyntheticEvent, useCallback, useEffect, useState } from "react";
import {
SyntheticEvent,
createContext,
useCallback,
useEffect,
useState,
} from "react";
import { Address, Hex, formatEther } from "viem";
import { validateAddress, validateETH } from "../utils/validators";
import { GenericField } from "../components/GenericField";
Expand Down Expand Up @@ -404,6 +410,8 @@ const EditProposal = ({
);
};

export const ProposalContext = createContext<Proposal | undefined>(undefined);

export const NewSafeProposal = () => {
const [proposal, setProposal] = useState<undefined | Proposal>(
DEFAULT_PROPOSAL,
Expand All @@ -428,22 +436,24 @@ export const NewSafeProposal = () => {
);

return (
<View paddingTop={4} paddingBottom={8} gap={8}>
<SafeInformation>
{isEditing && (
<EditProposal
proposal={proposal}
setProposal={setProposal}
setIsEditing={setIsEditing}
/>
)}
{!isEditing && proposal && (
<ViewProposal
proposal={proposal}
handleEditClicked={handleEditClicked}
/>
)}
</SafeInformation>
</View>
<ProposalContext.Provider value={proposal}>
<View paddingTop={4} paddingBottom={8} gap={8}>
<SafeInformation>
{isEditing && (
<EditProposal
proposal={proposal}
setProposal={setProposal}
setIsEditing={setIsEditing}
/>
)}
{!isEditing && proposal && (
<ViewProposal
proposal={proposal}
handleEditClicked={handleEditClicked}
/>
)}
</SafeInformation>
</View>
</ProposalContext.Provider>
);
};
2 changes: 1 addition & 1 deletion src/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Object.keys(contractNetworks).map((network) => {
return;
}
const viemChain = Object.values(chains).find(
(chain) => chain.id.toString() === network
(chain) => chain.id.toString() === network,
);

if (!viemChain) {
Expand Down
65 changes: 36 additions & 29 deletions src/components/SetOwnerModal.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { SyntheticEvent } from "react";
import { SyntheticEvent, useContext } from "react";
import { Button, Modal, Text, View, useToast } from "reshaped";
import { AddressView } from "./AddressView";
import { Address } from "viem";
import { Field, Form, Formik } from "formik";
import { GenericField } from "./GenericField";
import { yupAddress } from "../utils/validators";
import { number, object } from "yup";
import { useOutletContext, useSearchParams } from "react-router-dom";
import { useOutletContext } from "react-router-dom";
import { SafeContext } from "./Contexts";
import { ProposalContext } from "../app/NewSafeProposal";
import { useUpdateProposalViaQuery } from "../hooks/useUpdateProposalViaQuery";

export type OwnerAction =
| undefined
Expand Down Expand Up @@ -43,7 +45,9 @@ const ButtonPanel = ({
const AddOwnerModalContent = ({ onClose }: { onClose: () => void }) => {
const { safeInformation } = useOutletContext<SafeContext>();
const toast = useToast();
const [, setSearchParams] = useSearchParams();
const updateProposalQuery = useUpdateProposalViaQuery();
const currentProposal = useContext(ProposalContext);

return (
<Formik
initialValues={{ address: "0x", threshold: safeInformation?.threshold }}
Expand All @@ -58,16 +62,10 @@ const AddOwnerModalContent = ({ onClose }: { onClose: () => void }) => {
ownerAddress: address,
threshold: threshold,
});
setSearchParams({
proposal: JSON.stringify({
actions: [
{
data: addOwnerTx.data.data,
value: 0,
to: safeInformation.address,
},
],
}),
updateProposalQuery({
data: addOwnerTx.data.data,
value: "0",
to: safeInformation.address,
});
} catch (err: any) {
toast.show({ title: "Error Updating Safe", text: err.toString() });
Expand All @@ -76,7 +74,7 @@ const AddOwnerModalContent = ({ onClose }: { onClose: () => void }) => {
}}
>
<Form>
<Text variant="featured-2">Add Owner</Text>
<Text variant="featured-2">Add Signer</Text>
<Field name="address">
{GenericField({ label: "New User Address" })}
</Field>
Expand All @@ -102,25 +100,34 @@ const RemoveOwnerModalContent = ({
onClose: () => void;
target: string;
}) => {
const [_, setParams] = useSearchParams();
const { safeInformation } = useOutletContext<SafeContext>();
const updateProposalViaQuery = useUpdateProposalViaQuery();
const toaster = useToast();

const onSubmitClick = async ({ threshold }: any) => {
const removeOwnerTx = await safeInformation?.safeSdk.createRemoveOwnerTx({
ownerAddress: safeInformation!.address,
threshold: threshold,
});
if (!removeOwnerTx || !safeInformation) {
return;
try {
const removeOwnerTx = await safeInformation?.safeSdk2.createRemoveOwnerTx(
{
ownerAddress: target,
threshold: threshold,
},
);
if (!removeOwnerTx || !safeInformation) {
return;
}

updateProposalViaQuery({
data: removeOwnerTx.data.data,
value: "0",
to: safeInformation.address,
});
onClose();
} catch (err: any) {
toaster.show({
title: "Error Removing Owner",
text: `Error setting up transaction: ${err.toString()}`,
});
}
setParams({
proposal: JSON.stringify({
actions: [
{ data: removeOwnerTx.data, value: "0", to: safeInformation.address },
],
}),
});
onClose();
};
return (
<Formik
Expand Down
18 changes: 12 additions & 6 deletions src/hooks/useLoadProposalFromQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,20 @@ import { Proposal } from "../schemas/proposal";
export const queryKeys = {
targets: "targets",
calldatas: "calldatas",
values: "values"
};
values: "values",
nonce: "nonce",
} as const;

export const useLoadProposalFromQuery = () => {
const [proposal, setProposal] = useState<undefined | Proposal>();
const [params] = useSearchParams();

useEffect(() => {
const targets = params.get(queryKeys.targets)?.split("|");
const calldatas = params.get(queryKeys.calldatas)?.split("|");
const values = params.get(queryKeys.values)?.split("|");
const targets = params.get(queryKeys["targets"])?.split("|");
const calldatas = params.get(queryKeys["calldatas"])?.split("|");
const values = params.get(queryKeys["values"])?.split("|");
const nonce = params.get(queryKeys["nonce"]);

if (targets && calldatas) {
// ensure the 3 lengths are the same. check if values also has the same length if its not empty
// check the inverse of the above, if inverse is true, return:
Expand All @@ -32,7 +35,10 @@ export const useLoadProposalFromQuery = () => {
data: calldatas[index]!,
value: (values && values[index]) || "0",
}));
setProposal({ actions });

console.log({ actions, txt: "setting proposal" });

setProposal({ actions, ...(nonce ? { [queryKeys.nonce]: nonce } : {}) });

Check failure on line 41 in src/hooks/useLoadProposalFromQuery.ts

View workflow job for this annotation

GitHub Actions / build

Argument of type '{ nonce?: string | undefined; actions: { to: string; data: string; value: string; }[]; }' is not assignable to parameter of type 'SetStateAction<Proposal | undefined>'.

Check failure on line 41 in src/hooks/useLoadProposalFromQuery.ts

View workflow job for this annotation

GitHub Actions / build

Argument of type '{ nonce?: string | undefined; actions: { to: string; data: string; value: string; }[]; }' is not assignable to parameter of type 'SetStateAction<Proposal | undefined>'.
}
}, [params, setProposal]);

Expand Down
6 changes: 5 additions & 1 deletion src/hooks/useSetParamsFromQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ export const useRedirectToProposalWithNewParams = () => {
if (!proposal.actions?.length) {
return;
}
console.log("setting params", proposal.actions);
setParams({
[queryKeys.targets]: proposal.actions!.map((action) => action.to).join("|"),
[queryKeys.calldatas]: proposal.actions!.map((action) => action.data).join("|"),
[queryKeys.values]: proposal.actions!.map((action) => action.value).join("|"),
...(proposal.nonce
? {
[queryKeys.nonce]: proposal.nonce.toString(),
}
: {}),
});
},
[setParams],
Expand Down
19 changes: 19 additions & 0 deletions src/hooks/useUpdateProposalViaQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useCallback, useContext } from "react";
import { Proposal } from "../schemas/proposal";
import { ProposalContext } from "../app/NewSafeProposal";
import { useRedirectToProposalWithNewParams } from "./useSetParamsFromQuery";

export const useUpdateProposalViaQuery = () => {
const setParams = useRedirectToProposalWithNewParams();
const proposal = useContext(ProposalContext);

return useCallback(
(newAction: NonNullable<Proposal["actions"]>[0]) => {
setParams({
actions: [...(proposal?.actions || []), newAction],
nonce: proposal?.nonce,
});
},
[proposal, setParams],
);
};

0 comments on commit 938bde8

Please sign in to comment.