Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const SignerThresholdView = ({ actionView, safeData, isAdd }) => {
<span className="column pl-0 has-text-grey">Signature Threshold</span>
<div className="column pl-0">
<span className="has-text-weight-bold has-text-black">
{newThreshold} of{safeOwners.length} owner(s)
{newThreshold} of {safeOwners.length} owner(s)
</span>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const ThresholdView = ({ actionView, safeData }) => {
<div className="is-size-6">
<div className="pb-2">Signature Threshold</div>
<div className="pb-2 is-size-3 is-family-monospace has-text-black has-text-weight-bold">
{newThreshold} of{safeOwners?.length} owners
{newThreshold} of {safeOwners?.length} owners
</div>
<ProposedDateView timestamp={timestamp} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const EditThresholdForm = ({
<Svg name="Person" />
</div>
<div className="flex-1 is-flex is-align-items-center px-5 border-light-right has-text-black">
{newThreshold} of{Math.max(safeOwners.length, 1)} owner(s)
{newThreshold} of {Math.max(safeOwners.length, 1)} owner(s)
</div>
<div
className={minusSignerClasses.join(' ')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const EditThreshold = ({ treasury, newOwner, ownerToBeRemoved }) => {
const { openModal, closeModal } = useModalContext();
const history = useHistory();
const web3 = useContext(Web3Context);
const { setTreasury, proposeAddSigner, proposeRemoveSigner } = web3;
const { setAddressAlias, proposeAddSigner, proposeRemoveSigner } = web3;
const { address, safeOwners, threshold } = treasury;
const verifiedSafeOwners = safeOwners.filter((o) => o.verified);
let allSafeOwners;
Expand All @@ -36,15 +36,15 @@ const EditThreshold = ({ treasury, newOwner, ownerToBeRemoved }) => {

const onChangeThreshold = (isIncrease) => {
setNewThreshold((prevState) =>
isIncrease ? prevState + 1 : prevState - 1
(isIncrease ? prevState + 1 : prevState - 1)
);
};

const onConfirmAddOwner = async () => {
await proposeAddSigner(formatAddress(newOwner.address), newThreshold);
setTreasury(address, {
safeOwners: [...safeOwners, { ...newOwner, verified: false }],
});
if (newOwner.name) {
setAddressAlias(newOwner.address, newOwner.name)
}
closeModal();
history.push(`/safe/${address}`);
};
Expand Down Expand Up @@ -110,3 +110,4 @@ const EditThreshold = ({ treasury, newOwner, ownerToBeRemoved }) => {
};

export default EditThreshold;

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import { formatAddress, isAddr } from 'utils';
import Svg from 'library/Svg';
import EditThreshold from '../EditThreshold';

const AddSafeOwner = ({ treasury, safeOwners }) => {
const AddSafeOwner = ({
treasury,
safeOwners,
addressAliases,
setAddressAlias,
}) => {
const web3 = useContext(Web3Context);
const { openModal, closeModal } = useModalContext();
const { isAddressValid } = useAddressValidation(web3.injectedProvider);
Expand All @@ -22,24 +27,31 @@ const AddSafeOwner = ({ treasury, safeOwners }) => {
addressValid ? 'has-text-weight-bold' : 'disabled'
}`;

const isAddressExisting = (_safeOwners, newAddress) => {
const addr = formatAddress(newAddress);
return (
_safeOwners.filter((obj) => obj.address === addr && obj.verified)
.length !== 0
);
};
const onAddressChange = async (newAddress) => {
setAddress(newAddress);
const isValid =
isAddr(newAddress) &&
(await isAddressValid(newAddress)) &&
!isAddressExisting(safeOwners, newAddress);
setAddressValid(isValid);
};

const isAddressExisting = (safeOwners, newAddress) => {
const address = formatAddress(newAddress);
return (
safeOwners.filter((obj) => obj.address === address && obj.verified)
.length !== 0
);
if (addressAliases[newAddress]) {
setName(addressAliases[newAddress]);
}
};

const onNextClick = () => {
// Set Address Alias
if (name) {
setAddressAlias(address, name);
}
// Open Edit Threshold Modal
openModal(
<EditThreshold treasury={treasury} newOwner={{ address, name }} />,
{ headerTitle: 'Set A New Threshold' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@ import Svg from 'library/Svg';
import AddSafeOwner from './AddSafeOwner';
import RemoveSafeOwner from './RemoveSafeOwner';

const Owners = ({ treasury }) => {
const Owners = ({ treasury, addressAliases, setAddressAlias }) => {
const modalContext = useModalContext();
const { safeOwners } = treasury;
const verifiedSafeOwners = safeOwners.filter((o) => o.verified);
const ownersAddressClipboard = useClipboard();

const openAddOwnerModal = () => {
modalContext.openModal(
<AddSafeOwner treasury={treasury} safeOwners={safeOwners} />,
<AddSafeOwner
treasury={treasury}
safeOwners={safeOwners}
addressAliases={addressAliases}
setAddressAlias={setAddressAlias}
/>,
{
headerTitle: 'Add Owner',
}
Expand Down Expand Up @@ -51,7 +56,7 @@ const Owners = ({ treasury }) => {
verifiedSafeOwners.map((so, idx) => (
<div className="is-flex column is-full p-5" key={idx}>
<div className="px-2 mr-6" style={{ minWidth: 120 }}>
{so.name ?? `Signer #${idx + 1}`}
{addressAliases[so.address] ?? `Signer #${idx + 1}`}
</div>
<div className="flex-1">{so.address}</div>
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { useState } from 'react';

const EditSafeName = ({ name, onCancel, onSubmit }) => {
const [currSafeName, setCurrSafeName] = useState(name);
const [currSafeName, setCurrSafeName] = useState(name ?? '');

const isNameValid = currSafeName.trim().length > 0;

const onSubmitClick = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import React from 'react';
import { useModalContext } from 'contexts';
import { useClipboard } from 'hooks';
import { useClipboard, useAddressAliases } from 'hooks';
import EditSafeName from './EditSafeName';

const SafeDetailsSetting = ({ treasury, setTreasury }) => {
const modalContext = useModalContext();
const { name, address } = treasury;
const safeAddressClipboard = useClipboard();
const { setTreasuryAlias } = useAddressAliases();

const onEditNameSubmit = (newName) => {
setTreasuryAlias(address, newName);
modalContext.closeModal();
};
const openEditNameModal = () => {
modalContext.openModal(
<EditSafeName
Expand All @@ -16,10 +22,7 @@ const SafeDetailsSetting = ({ treasury, setTreasury }) => {
/>
);
};
const onEditNameSubmit = (newName) => {
setTreasury(address, { name: newName });
modalContext.closeModal();
};

return (
<div>
<div className="column p-0 mt-5 is-flex is-full">
Expand Down
8 changes: 7 additions & 1 deletion packages/client/src/components/SafeSettings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const SafeSettings = () => {
addCollection,
removeVault,
removeCollection,
addressAliases,
setAddressAlias
} = web3;
useEffect(() => {
(() => {
Expand All @@ -38,7 +40,11 @@ const SafeSettings = () => {
<>
<SafeDetailsSetting treasury={treasury} setTreasury={setTreasury} />
<SignatureThreshold treasury={treasury} />
<Owners treasury={treasury} proposeRemoveSigner={proposeRemoveSigner} />
<Owners
treasury={treasury}
addressAliases={addressAliases}
setAddressAlias={setAddressAlias}
/>
<TokenAsset
ref={scrollTo === '#tokenAsset' ? targetElementRef : null}
userAddr={address}
Expand Down
8 changes: 4 additions & 4 deletions packages/client/src/components/Safes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { Web3Consumer } from '../contexts/Web3';
import { isEmpty } from 'lodash';

function Safes(props) {
const { treasuries } = props.web3;
const { treasuryAliases } = props.web3;
const params = useParams();
const { address } = params;

if (isEmpty(treasuries)) {
if (isEmpty(treasuryAliases)) {
return (
<div className="has-background-transparent-black p-4 is-size-6">
<h3>
Expand All @@ -24,7 +24,7 @@ function Safes(props) {

return (
<aside className="menu">
{Object.entries(treasuries).map(([k, v], i) => {
{Object.entries(treasuryAliases).map(([k, v], i) => {
const isActive = address === v.address;
return (
<NavLink to={`/safe/${k}`} key={i}>
Expand Down Expand Up @@ -68,7 +68,7 @@ function Safes(props) {
}}
/>
<div className="flex-1 is-flex is-align-items-center px-2">
{v.name}
{v || k}
</div>
</div>
</NavLink>
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/components/SignatureRequirements.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function SignatureRequirements({
<Svg name="Person" />
</div>
<div className="flex-1 is-flex is-align-items-center px-5 border-light-right">
{signersAmount} of{Math.max(safeOwners.length, 1)} owner(s)
{signersAmount} of {Math.max(safeOwners.length, 1)} owner(s)
</div>
<div
className={minusSignerClasses.join(' ')}
Expand Down
9 changes: 7 additions & 2 deletions packages/client/src/contexts/Web3.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { useRouteMatch } from 'react-router-dom';
import { useFclUserBalance, useNFTs, useTreasury, useVaults } from '../hooks';
import { useFclUserBalance, useNFTs, useTreasury, useVaults, useAddressAliases } from 'hooks';
import { CURRENT_USER_SESSION_KEY } from 'constants/constants';
import * as fcl from '@onflow/fcl';
import { Buffer } from 'buffer';
Expand Down Expand Up @@ -75,8 +75,12 @@ export default function Web3Provider({
const match = useRouteMatch({
path: ['/safe/:address', '/safe/:address/:tab'],
});
const addressAliasProps = useAddressAliases();
const treasuryAddr = match?.params?.address;
const treasuryProps = useTreasury(treasuryAddr);
const treasuryProps = useTreasury(
treasuryAddr,
addressAliasProps.treasuryAliases
);
const nftProps = useNFTs(treasuryAddr);
const vaultProps = useVaults(treasuryAddr);

Expand All @@ -101,6 +105,7 @@ export default function Web3Provider({
...nftProps,
...vaultProps,
...treasuryProps,
...addressAliasProps,
...props,
};

Expand Down
26 changes: 22 additions & 4 deletions packages/client/src/flow/checkTreasuries.tx.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
export const GET_TREASURY = `
import DAOTreasuryV5 from 0xDAOTreasuryV5

pub struct SafeOwner {
pub var address: Address
pub var verified: Bool

init(address: Address){
self.address = address
self.verified = true
}
}

pub struct TreasuryInfo {
pub var uuid: UInt64
pub var signers: {Address: Bool}
pub var safeOwners: [SafeOwner]
pub var threshold: UInt

init(uuid: UInt64, signers: {Address: Bool}, threshold: UInt) {

init(uuid: UInt64, safeOwners: [SafeOwner], threshold: UInt) {
self.uuid = uuid
self.signers = signers
self.safeOwners = safeOwners
self.threshold = threshold
}
}
Expand All @@ -18,9 +29,16 @@ export const GET_TREASURY = `
.borrow<&DAOTreasuryV5.Treasury{DAOTreasuryV5.TreasuryPublic}>()
?? panic("A DAOTreasuryV5 doesn't exist here.")

let signers = treasury.borrowManagerPublic().getSigners()
let safeOwners: [SafeOwner] = []
for addr in signers.keys {
let owner = SafeOwner(address: addr)
safeOwners.append(owner)
}

return TreasuryInfo(
uuid: treasury.uuid,
signers: treasury.borrowManagerPublic().getSigners(),
safeOwners: safeOwners,
threshold: treasury.borrowManagerPublic().getThreshold()
)
}
Expand Down
1 change: 1 addition & 0 deletions packages/client/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export { default as useFlowFees } from './useFlowFees';
export { default as useErrorMessage } from './useErrorMessage';
export { default as useAccount } from './useAccount';
export { default as useContacts } from './useContacts';
export { default as useAddressAliases } from './useAddressAliases';
Loading