Skip to content

Commit

Permalink
Merge e9b97cd into edec103
Browse files Browse the repository at this point in the history
  • Loading branch information
0xvangrim authored Apr 20, 2022
2 parents edec103 + e9b97cd commit 0334f04
Show file tree
Hide file tree
Showing 13 changed files with 362 additions and 7 deletions.
11 changes: 11 additions & 0 deletions src/assets/images/info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/images/mint.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
@@ -0,0 +1,150 @@
import styled from 'styled-components';
import { Input } from 'components/Guilds/common/Form/Input';
import Avatar from 'components/Guilds/Avatar';
import { useEffect, useMemo } from 'react';
import { ActionEditorProps } from '..';
import { BigNumber, ethers } 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 { 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';
import { useERC20Info } from 'hooks/Guilds/ether-swr/erc20/useERC20Info';
import { useGuildConfig } from 'hooks/Guilds/ether-swr/guild/useGuildConfig';
import { useParams } from 'react-router-dom';
import NumericalInput from 'components/Guilds/common/Form/NumericalInput';

const Control = styled(Box)`
display: flex;
flex-direction: column;
margin: 0.75rem 0;
width: 100%;
`;

const ControlLabel = styled(Box)`
display: flex;
flex-direction: row;
margin-bottom: 0.75rem;
color: ${({ theme }) => theme.colors.proposalText.grey};
font-size: ${({ theme }) => theme.fontSizes.body};
font-weight: ${({ theme }) => theme.fontWeights.regular};
`;

const ControlRow = styled(Box)`
display: flex;
align-items: stretch;
height: 100%;
`;

const RepMintInput = styled(NumericalInput)`
${baseInputStyles}
display: flex;
align-items: center;
width: 100%;
&:hover,
&:focus {
border: 0.1rem solid ${({ theme }) => theme.colors.text};
}
`;

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

const Mint: React.FC<ActionEditorProps> = ({ decodedCall, updateCall }) => {
// parse transfer state from calls
const [repPercent, setRepPercent] = useState(0);
const [repAmount, setRepAmount] = useState(0);
const { guild_id: guildId } =
useParams<{ chain_name?: string; guild_id?: string }>();
const { data } = useGuildConfig(guildId);
const { data: tokenData } = useERC20Info(data?.token);
const totalSupply = useBigNumberToNumber(tokenData?.totalSupply, 18);

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

const { imageUrl } = useENSAvatar(parsedData?.toAddress, MAINNET_ID);

const setCallDataAmount = (value: string) => {
const amount = value ? ethers.utils.parseUnits(value) : null;
updateCall({
...decodedCall,
args: {
...decodedCall.args,
amount,
},
});
};

useEffect(() => {
setRepAmount((repPercent / 100) * totalSupply);
if (repAmount) {
setCallDataAmount(repAmount.toString());
}
}, [repPercent, repAmount, totalSupply]);

const handleRepChange = (e: number) => {
if (e) {
setRepPercent(e);
}
};
return (
<div>
<Control>
<ControlLabel>
Recipient
<StyledIcon src={Info} />
</ControlLabel>
<ControlRow>
<Input
value={shortenAddress(parsedData?.toAddress)}
icon={
<Avatar
src={imageUrl}
defaultSeed={parsedData?.toAddress}
size={18}
/>
}
readOnly
/>
</ControlRow>
</Control>
<ControlRow>
<Control>
<ControlLabel>
Reputation in % <StyledIcon src={Info} />
</ControlLabel>
<ControlRow>
<RepMintInput value={repPercent} onUserInput={handleRepChange} />
</ControlRow>
</Control>
</ControlRow>
<ControlRow>
<Control>
<ControlLabel>
Reputation Amount <StyledIcon src={Info} />
</ControlLabel>
<ControlRow>
<RepMintInput
value={repAmount}
onUserInput={handleRepChange}
readOnly
/>
</ControlRow>
</Control>
</ControlRow>
</div>
);
};

export default Mint;
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import Avatar from 'components/Guilds/Avatar';
import useENSAvatar from 'hooks/Guilds/ether-swr/ens/useENSAvatar';
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 { BigNumber } from 'ethers';
import useBigNumberToNumber from 'hooks/Guilds/conversions/useBigNumberToNumber';
import { useERC20Info } from 'hooks/Guilds/ether-swr/erc20/useERC20Info';
import { useGuildConfig } from 'hooks/Guilds/ether-swr/guild/useGuildConfig';
import { useParams } from 'react-router-dom';

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

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

const REPMintInfoLine: React.FC<ActionViewProps> = ({ decodedCall }) => {
const { guild_id: guildId } =
useParams<{ chain_name?: string; guild_id?: string }>();
const { data } = useGuildConfig(guildId);
const { data: tokenData } = useERC20Info(data?.token);
const totalSupply = useBigNumberToNumber(tokenData?.totalSupply, 18);

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);

const roundedRepAmount = useBigNumberToNumber(parsedData?.amount, 16, 3);
const roundedRepPercent = roundedRepAmount / totalSupply;

return (
<>
<Segment>
<StyledMintIcon src={Mint} />
</Segment>
<Segment>Mint {roundedRepPercent} %</Segment>
<Segment>
<FiArrowRight />
</Segment>
<Segment>
<Avatar defaultSeed={parsedData?.toAddress} src={imageUrl} size={24} />
</Segment>
<Segment>{ensName || shortenAddress(parsedData?.toAddress)}</Segment>
</>
);
};

export default REPMintInfoLine;
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Avatar from 'components/Guilds/Avatar';
import useBigNumberToNumber from 'hooks/Guilds/conversions/useBigNumberToNumber';
import useENSAvatar from 'hooks/Guilds/ether-swr/ens/useENSAvatar';
import { MAINNET_ID, shortenAddress } from 'utils';
import { ActionViewProps } from '..';
import { Segment } from '../common/infoLine';
import { DetailCell, DetailHeader, DetailRow } from '../common/summary';
import { useTotalSupply } from 'hooks/Guilds/guild/useTotalSupply';
import { useTokenData } from 'hooks/Guilds/guild/useTokenData';
const REPMintSummary: React.FC<ActionViewProps> = ({ decodedCall }) => {
const { parsedData } = useTotalSupply({ decodedCall });
const { tokenData } = useTokenData();
const { ensName, imageUrl } = useENSAvatar(parsedData?.toAddress, MAINNET_ID);

const roundedRepAmount = useBigNumberToNumber(parsedData?.amount, 18, 3);

return (
<>
<DetailHeader>
<DetailCell>Receiver</DetailCell>
<DetailCell>Amount</DetailCell>
</DetailHeader>

<DetailRow>
<DetailCell>
<Segment>
<Avatar
defaultSeed={parsedData?.toAddress}
src={imageUrl}
size={24}
/>
</Segment>
<Segment>{ensName || shortenAddress(parsedData?.toAddress)}</Segment>
</DetailCell>
<DetailCell>
{roundedRepAmount} {tokenData?.name}
</DetailCell>
</DetailRow>
</>
);
};

export default REPMintSummary;
27 changes: 24 additions & 3 deletions src/components/Guilds/ActionsBuilder/SupportedActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { BigNumber, utils } from 'ethers';
import { DeepPartial, RequireAtLeastOne } from 'utils/types';
import { DecodedAction, DecodedCall, SupportedAction } from '../types';
import ERC20ABI from '../../../../abis/ERC20.json';
import ERC20SnapshotRep from '../../../../contracts/ERC20SnapshotRep.json';
import ERC20TransferEditor from './ERC20Transfer/ERC20TransferEditor';
import ERC20TransferInfoLine from './ERC20Transfer/ERC20TransferInfoLine';
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 @@ -37,15 +40,20 @@ export const supportedActions: Record<
summaryView: ERC20TransferSummary,
editor: ERC20TransferEditor,
},
[SupportedAction.REP_MINT]: {
title: 'Mint Reputation',
infoLineView: REPMintInfoLine,
summaryView: REPMintSummary,
editor: REPMintEditor,
},
[SupportedAction.GENERIC_CALL]: {
title: 'Generic Call',
infoLineView: () => <div>Generic Call</div>,
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 @@ -62,6 +70,19 @@ export const defaultValues: Record<
},
},
},
[SupportedAction.REP_MINT]: {
contract: ERC20SnapshotRepContract,
decodedCall: {
function: ERC20SnapshotRepContract.getFunction('mint'),
to: '',
value: BigNumber.from(0),
args: {
to: '',
amount: BigNumber.from(0),
},
},
},

[SupportedAction.GENERIC_CALL]: {},
};

Expand Down
1 change: 1 addition & 0 deletions src/components/Guilds/ActionsBuilder/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { utils } from 'ethers';

export enum SupportedAction {
ERC20_TRANSFER = 'ERC20_TRANSFER',
REP_MINT = 'REP_MINT',
GENERIC_CALL = 'GENERIC_CALL',
}

Expand Down
Loading

0 comments on commit 0334f04

Please sign in to comment.