Skip to content

Commit

Permalink
Feat: incorporate network fees in Create Payment
Browse files Browse the repository at this point in the history
  • Loading branch information
dit7ya committed Mar 29, 2022
1 parent d29bc2c commit ae8803e
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import { ActionForm } from '~core/Fields';

import { Address } from '~types/index';
import { ActionTypes } from '~redux/index';
import { useMembersSubscription } from '~data/index';
import { useMembersSubscription, useNetworkContracts } from '~data/index';
import { getTokenDecimalsWithFallback } from '~utils/tokens';
import { pipe, withMeta, mapPayload } from '~utils/actions';
import { WizardDialogType } from '~utils/hooks';

import DialogForm from './CreatePaymentDialogForm';
import DialogForm, { calculateFee } from './CreatePaymentDialogForm';

const MSG = defineMessages({
amountZero: {
Expand All @@ -33,7 +33,7 @@ export interface FormValues {
forceAction: boolean;
domainId: string;
recipient: Address;
amount: string;
amount: string; // Amount the receiver finally gets, the initiator pays this plus network fee
tokenAddress: Address;
annotation: string;
motionDomainId: string;
Expand Down Expand Up @@ -93,6 +93,8 @@ const CreatePaymentDialog = ({
variables: { colonyAddress },
});

const { feeInverse: networkFeeInverse } = useNetworkContracts();

const transform = useCallback(
pipe(
mapPayload((payload) => {
Expand All @@ -114,14 +116,18 @@ const CreatePaymentDialog = ({
selectedToken && selectedToken.decimals,
);

const amountWithFees = networkFeeInverse
? calculateFee(amount, networkFeeInverse, decimals).totalToPay
: amount;

return {
colonyName,
colonyAddress,
recipientAddress: walletAddress,
domainId,
singlePayment: {
tokenAddress,
amount,
amount: amountWithFees, // NOTE: The contract only sees this amount
decimals,
},
annotationMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
text-align: right;
}

.domainPotBalance {
.domainPotBalance, .networkFee {
font-size: var(--size-tiny);
font-weight: var(--weight-bold);
text-align: right;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const tokenAmountSelect: string;
export const tokenAmountContainer: string;
export const tokenAmountUsd: string;
export const domainPotBalance: string;
export const networkFee: string;
export const domainSelects: string;
export const tokenAmountInputContainer: string;
export const singleUserContainer: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
useLoggedInUser,
useTokenBalancesForDomainsLazyQuery,
AnyUser,
useNetworkContracts,
} from '~data/index';
import {
getBalanceFromToken,
Expand Down Expand Up @@ -64,6 +65,10 @@ const MSG = defineMessages({
id: 'dashboard.CreatePaymentDialog.CreatePaymentDialogForm.amount',
defaultMessage: 'Amount',
},
fee: {
id: 'dashboard.CreatePaymentDialog.CreatePaymentDialogForm.fee',
defaultMessage: 'Network fee: {fee} {symbol}',
},
token: {
id: 'dashboard.CreatePaymentDialog.CreatePaymentDialogForm.address',
defaultMessage: 'Token',
Expand Down Expand Up @@ -114,6 +119,22 @@ const supRenderAvatar = (address: Address, item: ItemDataType<AnyUser>) => (
<UserAvatar address={address} user={item} size="xs" notSet={false} />
);

export const calculateFee = (
receivedAmount: string, // amount that the recipient finally receives
feeInverse: string,
decimals: number,
): { feesInWei: string; totalToPay: string } => {
const amountInWei = moveDecimal(receivedAmount, decimals);
const totalToPay = bigNumberify(amountInWei)
.mul(feeInverse)
.div(bigNumberify(feeInverse).sub(1)); // this formula is easily derivable
const feesInWei = totalToPay.sub(amountInWei);
return {
feesInWei: feesInWei.toString(),
totalToPay: moveDecimal(totalToPay, -1 * decimals),
}; // NOTE: seems like moveDecimal does not have strict typing
};

const CreatePaymentDialogForm = ({
back,
colony,
Expand Down Expand Up @@ -313,6 +334,8 @@ const CreatePaymentDialogForm = ({

const inputDisabled = !canMakePayment || onlyForceAction || isSubmitting;

const { feeInverse: networkFeeInverse } = useNetworkContracts();

return (
<>
<DialogSection appearance={{ theme: 'sidePadding' }}>
Expand Down Expand Up @@ -427,7 +450,44 @@ const CreatePaymentDialogForm = ({
*/
forcedFieldError={customAmountError}
/>

{networkFeeInverse &&
values.amount &&
values.amount !== '0' &&
values.amount !== '0.' &&
values.amount !== '.' && (
<div className={styles.networkFee}>
<FormattedMessage
{...MSG.fee}
values={{
fee: (
<Numeral
appearance={{
size: 'small',
theme: 'grey',
}}
value={
calculateFee(
values.amount,
networkFeeInverse,
getTokenDecimalsWithFallback(
selectedToken?.decimals,
),
).feesInWei
}
unit={getTokenDecimalsWithFallback(
selectedToken && selectedToken.decimals,
)}
truncate={3}
/>
),
symbol: (selectedToken && selectedToken.symbol) || '???',
}}
/>
</div>
)}
</div>

<div className={styles.tokenAmountContainer}>
<div className={styles.tokenAmountSelect}>
<TokenSymbolSelector
Expand Down

0 comments on commit ae8803e

Please sign in to comment.