Skip to content

Commit

Permalink
feat: enabled full functionality according to specs. Last part is to …
Browse files Browse the repository at this point in the history
…sync with a contract
  • Loading branch information
Kenny Chung committed Apr 10, 2022
1 parent 473d33d commit 930a567
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ const Transfer: React.FC<ActionEditorProps> = ({ decodedCall, updateCall }) => {
// parse transfer state from calls
const parsedData = useMemo<TransferState>(() => {
if (!decodedCall) return null;

return {
source: decodedCall.from,
tokenAddress: decodedCall.to,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
import styled from 'styled-components';
import { Input } from 'components/Guilds/common/Form/Input';
import Avatar from 'components/Guilds/Avatar';
import { useWeb3React } from '@web3-react/core';
import { useMemo } from 'react';
import { ActionEditorProps } from '..';
import { utils } from 'ethers';
import { BigNumber } from 'ethers';
import useENSAvatar from 'hooks/Guilds/ether-swr/ens/useENSAvatar';
import { Box } from 'components/Guilds/common/Layout';
import { shortenAddress, MAINNET_ID } from 'utils';
import NumericalInput from 'components/Guilds/common/Form/NumericalInput';
import { baseInputStyles } from 'components/Guilds/common/Form/Input';
import { ReactComponent as Info } from '../../../../../assets/images/info.svg';
import StyledIcon from 'components/Guilds/common/SVG';
// import useBigNumberToNumber from 'hooks/Guilds/conversions/useBigNumberToNumber';
import { useState } from 'react';

const Control = styled(Box)`
display: flex;
Expand All @@ -36,7 +36,7 @@ const ControlRow = styled(Box)`
height: 100%;
`;

const RepMintInput = styled(NumericalInput)`
const RepMintInput = styled(Input)`
${baseInputStyles}
display: flex;
align-items: center;
Expand All @@ -47,34 +47,61 @@ const RepMintInput = styled(NumericalInput)`
}
`;

// interface REPMintState {
// source: string;
// tokenAddress: string;
// amount: BigNumber;
// destination: string;
// }
interface REPMintState {
toAddress: string;
amount: BigNumber;
}

const Mint: React.FC<ActionEditorProps> = ({ decodedCall }) => {
const Mint: React.FC<ActionEditorProps> = ({ decodedCall, updateCall }) => {
// parse transfer state from calls
// const parsedData = useMemo<REPMintState>(() => {
// if (!decodedCall) return null;
console.log({ decodedCall });
const [repPercent, setRepPercent] = useState(0);
const [repAmount, setRepAmount] = useState(0);
const parsedData = useMemo<REPMintState>(() => {
if (!decodedCall) return null;
return {
toAddress: decodedCall.args.to,
amount: decodedCall.args.amount,
};
}, [decodedCall]);

// return {
// source: decodedCall.from,
// tokenAddress: decodedCall.to,
// amount: decodedCall.args._value,
// destination: decodedCall.args._to,
// };
// }, [decodedCall]);
console.log({ parsedData });
const { imageUrl } = useENSAvatar(parsedData?.toAddress, MAINNET_ID);

const { account: userAddress } = useWeb3React();
const { imageUrl } = useENSAvatar(userAddress, MAINNET_ID);
const setCallDataAmount = (value: string) => {
const amount = value ? BigNumber.from(value) : null;
updateCall({
...decodedCall,
args: {
...decodedCall.args,
amount,
},
});
};

const validations = useMemo(() => {
return {
destination: utils.isAddress(userAddress),
};
}, [userAddress]);
const handleRepPercentChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.value) {
setRepPercent(parseInt(e.target.value));
setRepAmount(parseInt(e.target.value) * 100);
setCallDataAmount((parseInt(e.target.value) * 100).toString());
} else {
setRepPercent(0);
setRepAmount(0);
setCallDataAmount('0');
}
};

const handleRepAmountChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.value) {
setRepAmount(parseInt(e.target.value));
setRepPercent(parseInt(e.target.value) / 100);
setCallDataAmount(e.target.value);
} else {
setRepPercent(0);
setRepAmount(0);
setCallDataAmount('0');
}
};

return (
<div>
Expand All @@ -85,11 +112,13 @@ const Mint: React.FC<ActionEditorProps> = ({ decodedCall }) => {
</ControlLabel>
<ControlRow>
<Input
value={shortenAddress(userAddress)}
value={shortenAddress(parsedData?.toAddress)}
icon={
validations.destination && (
<Avatar src={imageUrl} defaultSeed={userAddress} size={18} />
)
<Avatar
src={imageUrl}
defaultSeed={parsedData?.toAddress}
size={18}
/>
}
readOnly
/>
Expand All @@ -101,7 +130,10 @@ const Mint: React.FC<ActionEditorProps> = ({ decodedCall }) => {
Reputation in % <StyledIcon src={Info} />
</ControlLabel>
<ControlRow>
<RepMintInput value={''} onUserInput={''} />
<RepMintInput
value={repPercent}
onChange={handleRepPercentChange}
/>
</ControlRow>
</Control>
</ControlRow>
Expand All @@ -111,7 +143,7 @@ const Mint: React.FC<ActionEditorProps> = ({ decodedCall }) => {
Reputation Amount <StyledIcon src={Info} />
</ControlLabel>
<ControlRow>
<RepMintInput value={''} onUserInput={''} />
<RepMintInput value={repAmount} onChange={handleRepAmountChange} />
</ControlRow>
</Control>
</ControlRow>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,52 @@
import Avatar from 'components/Guilds/Avatar';
import useENSAvatar from 'hooks/Guilds/ether-swr/ens/useENSAvatar';
// import { useMemo } from 'react';
import { useMemo } from 'react';
import { FiArrowRight } from 'react-icons/fi';
import { MAINNET_ID, shortenAddress } from 'utils';
import { ActionViewProps } from '..';
import { Segment } from '../common/infoLine';
import { ReactComponent as Mint } from '../../../../../assets/images/mint.svg';
import StyledIcon from 'components/Guilds/common/SVG';
import styled from 'styled-components';
import { useWeb3React } from '@web3-react/core';
import { BigNumber } from 'ethers';
import useBigNumberToNumber from 'hooks/Guilds/conversions/useBigNumberToNumber';

const StyledMintIcon = styled(StyledIcon)`
margin: 0;
`;

interface REPMintState {
guildAddress: string;
toAddress: string;
amount: BigNumber;
}

const REPMintInfoLine: React.FC<ActionViewProps> = ({ decodedCall }) => {
const { account: userAddress } = useWeb3React();
const { ensName, imageUrl } = useENSAvatar(userAddress, MAINNET_ID);
// const parsedData = useMemo(() => {
// if (!decodedCall) return null;
const parsedData = useMemo<REPMintState>(() => {
if (!decodedCall) return null;
return {
guildAddress: decodedCall.to,
toAddress: decodedCall.args.to,
amount: decodedCall.args.amount,
};
}, [decodedCall]);
const { ensName, imageUrl } = useENSAvatar(parsedData?.toAddress, MAINNET_ID);

// return {
// tokenAddress: decodedCall.to,
// amount: BigNumber.from(decodedCall.args._value),
// source: decodedCall.from,
// destination: decodedCall.args._to as string,
// };
// }, [decodedCall]);
const roundedRepAmount = useBigNumberToNumber(parsedData?.amount, 1, 2) * 10;

return (
<>
<Segment>
<StyledMintIcon src={Mint} />
</Segment>
<Segment>Mint {''}</Segment>
<Segment>Mint {roundedRepAmount} %</Segment>
<Segment>
<FiArrowRight />
</Segment>
<Segment>
<Avatar defaultSeed={userAddress} src={imageUrl} size={24} />
<Avatar defaultSeed={parsedData?.toAddress} src={imageUrl} size={24} />
</Segment>
<Segment>{ensName || shortenAddress(userAddress)}</Segment>
<Segment>{ensName || shortenAddress(parsedData?.toAddress)}</Segment>
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import Avatar from 'components/Guilds/Avatar';
import { BigNumber } from 'ethers';
import useBigNumberToNumber from 'hooks/Guilds/conversions/useBigNumberToNumber';
import useENSAvatar from 'hooks/Guilds/ether-swr/ens/useENSAvatar';
// import { useMemo } from 'react';
import { useMemo } from 'react';
import { MAINNET_ID, shortenAddress } from 'utils';
import { ActionViewProps } from '..';
import { Segment } from '../common/infoLine';
import { DetailCell, DetailHeader, DetailRow } from '../common/summary';
import { useWeb3React } from '@web3-react/core';

interface REPMintState {
toAddress: string;
amount: BigNumber;
}

const REPMintSummary: React.FC<ActionViewProps> = ({ decodedCall }) => {
// const parsedData = useMemo(() => {
// if (!decodedCall) return null;
const parsedData = useMemo<REPMintState>(() => {
if (!decodedCall) return null;
return {
toAddress: decodedCall.args.to,
amount: decodedCall.args.amount,
};
}, [decodedCall]);

// return {
// tokenAddress: decodedCall.to,
// amount: BigNumber.from(decodedCall.args._value),
// source: decodedCall.from,
// destination: decodedCall.args._to,
// };
// }, [decodedCall]);
const { ensName, imageUrl } = useENSAvatar(parsedData?.toAddress, MAINNET_ID);

const { account: userAddress } = useWeb3React();
const { ensName, imageUrl } = useENSAvatar(userAddress, MAINNET_ID);
const roundedRepAmount = useBigNumberToNumber(parsedData?.amount, 1, 3) * 10;

return (
<>
Expand All @@ -32,11 +36,15 @@ const REPMintSummary: React.FC<ActionViewProps> = ({ decodedCall }) => {
<DetailRow>
<DetailCell>
<Segment>
<Avatar defaultSeed={userAddress} src={imageUrl} size={24} />
<Avatar
defaultSeed={parsedData?.toAddress}
src={imageUrl}
size={24}
/>
</Segment>
<Segment>{ensName || shortenAddress(userAddress)}</Segment>
<Segment>{ensName || shortenAddress(parsedData?.toAddress)}</Segment>
</DetailCell>
<DetailCell>100 REP</DetailCell>
<DetailCell>{roundedRepAmount} REP</DetailCell>
</DetailRow>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import ERC20TransferSummary from './ERC20Transfer/ERC20TransferSummary';
import REPMintEditor from './REPMint/REPMintEditor';
import REPMintInfoLine from './REPMint/REPMintInfoLine';
import REPMintSummary from './REPMint/REPMintSummary';

export interface SupportedActionMetadata {
title: string;
}
Expand Down Expand Up @@ -53,10 +52,8 @@ export const supportedActions: Record<
editor: () => <div>Generic Call Editor</div>,
},
};

const ERC20Contract = new utils.Interface(ERC20ABI);
const ERC20SnapshotRepContract = new utils.Interface(ERC20SnapshotRep.abi);

export const defaultValues: Record<
SupportedAction,
DeepPartial<DecodedAction>
Expand All @@ -74,14 +71,14 @@ export const defaultValues: Record<
},
},
[SupportedAction.REP_MINT]: {
contract: ERC20Contract,
contract: ERC20SnapshotRepContract,
decodedCall: {
function: ERC20SnapshotRepContract.getFunction('mint'),
to: '',
value: BigNumber.from(0),
args: {
_to: '',
_value: BigNumber.from(0),
to: '',
amount: BigNumber.from(0),
},
},
},
Expand Down
5 changes: 4 additions & 1 deletion src/components/Guilds/ActionsModal/ContractsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ const ContractsList: React.FC<ContractsListProps> = ({
<SectionWrapper>
<SectionTitle>External Contracts</SectionTitle>
{contracts?.map(contract => (
<ActionsButton onClick={() => onSelect(contract)}>
<ActionsButton
key={contract.title}
onClick={() => onSelect(contract)}
>
<ButtonLabel>{contract.title}</ButtonLabel>
<ButtonDetail>
{contract.functions?.length}{' '}
Expand Down
8 changes: 7 additions & 1 deletion src/components/Guilds/ActionsModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Modal } from '../common/Modal';
import ContractActionsList from './ContractActionsList';
import ContractsList from './ContractsList';
import ParamsModal from './ParamsModal';
import { useWeb3React } from '@web3-react/core';

export const EditorWrapper = styled.div`
margin: 1.25rem;
Expand All @@ -40,7 +41,7 @@ const ActionModal: React.FC<ActionModalProps> = ({
onAddAction,
}) => {
const { guild_id: guildId } = useParams<{ guild_id?: string }>();

const { account: walletAddress } = useWeb3React();
// Supported Actions
const [selectedAction, setSelectedAction] = useState<SupportedAction>(null);
const [selectedActionContract, setSelectedActionContract] =
Expand Down Expand Up @@ -128,6 +129,11 @@ const ActionModal: React.FC<ActionModalProps> = ({

defaultDecodedAction.decodedCall.from = guildId;
defaultDecodedAction.decodedCall.callType = action;
switch (action) {
case SupportedAction.REP_MINT:
defaultDecodedAction.decodedCall.args.to = walletAddress;
break;
}
setData(defaultDecodedAction.decodedCall);
setSelectedAction(action);
setSelectedActionContract(defaultDecodedAction.contract);
Expand Down

0 comments on commit 930a567

Please sign in to comment.