Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(transfer to L2): max amount #62

Merged
merged 12 commits into from
Jan 18, 2022
Merged
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"react-redux": "^7.2.6",
"react-scripts": "4.0.3",
"starknet": "^2.5.0",
"use-async-memo": "^1.2.3",
"use-deep-compare-effect": "^1.8.1",
"use-wallet": "^0.13.4",
"uuid": "^8.3.2",
Expand Down
13 changes: 11 additions & 2 deletions src/api/bridge.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {parseToDecimals, parseToFelt, parseToUint256} from '../utils';
import {l1_sendTransaction, l2_sendTransaction} from '../utils/contract';
import {parseFromDecimals, parseToDecimals, parseToFelt, parseToUint256} from '../utils';
import {l1_callContract, l1_sendTransaction, l2_sendTransaction} from '../utils/contract';

export const deposit = async ({recipient, amount, decimals, contract, options, emitter}) => {
try {
Expand Down Expand Up @@ -48,6 +48,15 @@ export const withdraw = async ({recipient, amount, decimals, contract, emitter})
}
};

export const maxDeposit = async ({decimals, contract}) => {
try {
const maxDeposit = await l1_callContract(contract, 'maxDeposit');
return parseFromDecimals(maxDeposit, decimals);
} catch (ex) {
return Promise.reject(ex);
}
};

export const initiateWithdraw = async ({recipient, amount, decimals, contract}) => {
try {
return l2_sendTransaction(contract, 'initiate_withdraw', {
Expand Down
1 change: 1 addition & 0 deletions src/components/Features/Transfer/Transfer.hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const useTransferData = () => {
return {
...useSelector(selectTransfer),
selectedToken: useSelectedToken(),
symbol: useSelector(selectSymbol),
isL1: useSelector(toL2Selector),
isL2: useSelector(toL1Selector),
fromNetwork: useSelector(fromNetworkSelector),
Expand Down
27 changes: 19 additions & 8 deletions src/components/Features/Transfer/Transfer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {useEffect, useState} from 'react';

import {ActionType, NetworkType} from '../../../enums';
import {useTransferToL1, useTransferToL2} from '../../../hooks';
import {useMaxAmount, useTransferToL1, useTransferToL2} from '../../../hooks';
import {useL1Token, useL2Token, useTokens} from '../../../providers/TokensProvider';
import {
Loading,
Expand All @@ -16,22 +16,24 @@ import {LoadingSize} from '../../UI/Loading/Loading.enums';
import {useBridgeActions} from '../Bridge/Bridge.hooks';
import {useAmount, useIsL1, useIsL2, useTransferActions, useTransferData} from './Transfer.hooks';
import styles from './Transfer.module.scss';
import {INSUFFICIENT_BALANCE_ERROR_MSG} from './Transfer.strings';
import {INSUFFICIENT_BALANCE_ERROR_MSG, MAX_AMOUNT_ERROR_MSG} from './Transfer.strings';

export const Transfer = () => {
const [isL1, swapToL1] = useIsL1();
const [isL2, swapToL2] = useIsL2();
const [amount, setAmount] = useAmount();
const [hasInputError, setHasInputError] = useState(false);
const [errorMsg, setErrorMsg] = useState('');
const [isButtonDisabled, setIsButtonDisabled] = useState(true);
const {showSelectTokenMenu} = useBridgeActions();
const {selectedToken, action} = useTransferData();
const {selectedToken, action, symbol} = useTransferData();
const {selectToken} = useTransferActions();
const {tokens} = useTokens();
const transferToL2 = useTransferToL2();
const transferToL1 = useTransferToL1();
const {tokens} = useTokens();
const getL1Token = useL1Token();
const getL2Token = useL2Token();
const maxAmount = useMaxAmount();

useEffect(() => {
if (!selectedToken) {
Expand All @@ -42,21 +44,30 @@ export const Transfer = () => {
useEffect(() => {
if (selectedToken) {
setHasInputError(false);
if (selectedToken.isLoading || Math.ceil(amount) === 0) {
if (selectedToken.isLoading || Math.ceil(amount) === 0 || (isL1 && !maxAmount)) {
setIsButtonDisabled(true);
} else {
if (amount > selectedToken.balance) {
setHasInputError(true);
setErrorMsg(INSUFFICIENT_BALANCE_ERROR_MSG);
setIsButtonDisabled(true);
} else if (isL1 && amount > maxAmount) {
setHasInputError(true);
setErrorMsg(MAX_AMOUNT_ERROR_MSG(maxAmount, symbol));
setIsButtonDisabled(true);
} else {
setIsButtonDisabled(false);
}
}
}
}, [amount, selectedToken]);
}, [amount, selectedToken, maxAmount, isL1]);

const onMaxClick = () => {
setAmount(selectedToken.balance.toString());
try {
setAmount(Math.min(selectedToken.balance, Number(maxAmount)));
} catch (ex) {
setAmount(selectedToken.balance);
}
};

const onInputChange = event => {
Expand Down Expand Up @@ -111,7 +122,7 @@ export const Transfer = () => {
onMaxClick={onMaxClick}
onTokenSelect={showSelectTokenMenu}
/>
{hasInputError && <div className={styles.errorMsg}>{INSUFFICIENT_BALANCE_ERROR_MSG}</div>}
{hasInputError && <div className={styles.errorMsg}>{errorMsg}</div>}
<TransferButton isDisabled={isButtonDisabled} onClick={onTransferClick} />
</>
);
Expand Down
5 changes: 4 additions & 1 deletion src/components/Features/Transfer/Transfer.strings.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import {getString} from '../../../utils';
import {evaluate, getString} from '../../../utils';

export const INSUFFICIENT_BALANCE_ERROR_MSG = getString(
'menus.transfer.insufficient_balance_error_msg'
);

export const MAX_AMOUNT_ERROR_MSG = (maxAmount, symbol) =>
evaluate(getString('menus.transfer.max_amount_error_msg'), {maxAmount, symbol});
1 change: 1 addition & 0 deletions src/config/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"to_txt": "to",
"from_txt": "from",
"insufficient_balance_error_msg": "Insufficient balance",
"max_amount_error_msg": "StarkNet Alpha Limitation: transfer to StarkNet limited to {{maxAmount}} {{symbol}}.",
"max_btn_txt": "Max",
"balance_title_txt": "Available balance",
"input_placeholder_txt": "0.00",
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from './useTransfer';
export * from './useConfig';
export * from './useEventListener';
export * from './useTransferProgress';
export * from './useMaxAmount';
30 changes: 30 additions & 0 deletions src/hooks/useMaxAmount.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {useAsyncMemo} from 'use-async-memo';

import {maxDeposit} from '../api/bridge';
import {useTransferData} from '../components/Features/Transfer/Transfer.hooks';
import {useTokenBridgeContract} from './useContract';

const cache = {};

export const useMaxAmount = () => {
const {symbol, isL1, selectedToken} = useTransferData();
const getTokenBridgeContract = useTokenBridgeContract();

const fetchMaxAmount = async () => {
const {decimals, bridgeAddress} = selectedToken;
const contract = getTokenBridgeContract(bridgeAddress);
return await maxDeposit({decimals, contract});
};

return useAsyncMemo(async () => {
if (symbol && isL1) {
if (!cache[symbol]) {
const value = await fetchMaxAmount();
cache[symbol] = value;
return value;
}
return cache[symbol];
}
return null;
}, [symbol, isL1]);
};
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16374,6 +16374,11 @@ usb@^1.6.0:
node-addon-api "^4.2.0"
node-gyp-build "^4.3.0"

use-async-memo@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/use-async-memo/-/use-async-memo-1.2.3.tgz#fe49d7ae1cd850199cf9e4a8ee483e31ed85659f"
integrity sha512-AjZ1Wy1vfOSlaxohqoLIpauV+jwph/p0N72PBzxeEcjrZ4Mf/4o1Vav4bLaAPYuHLJZo+4M/4TIcAk7XC6H98g==

use-deep-compare-effect@^1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/use-deep-compare-effect/-/use-deep-compare-effect-1.8.1.tgz#ef0ce3b3271edb801da1ec23bf0754ef4189d0c6"
Expand Down