From cc55640c6c22c0b4fbbaf4d2db7a591c6a9f84d0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 12:43:51 +0100 Subject: [PATCH 01/18] necessary components for exchange --- packages/react-app/src/components/AmountIn.js | 1 + packages/react-app/src/components/AmountOut.js | 0 packages/react-app/src/components/Balance.js | 0 packages/react-app/src/components/index.js | 5 ++++- 4 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 packages/react-app/src/components/AmountIn.js create mode 100644 packages/react-app/src/components/AmountOut.js create mode 100644 packages/react-app/src/components/Balance.js diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/packages/react-app/src/components/AmountIn.js @@ -0,0 +1 @@ + diff --git a/packages/react-app/src/components/AmountOut.js b/packages/react-app/src/components/AmountOut.js new file mode 100644 index 0000000..e69de29 diff --git a/packages/react-app/src/components/Balance.js b/packages/react-app/src/components/Balance.js new file mode 100644 index 0000000..e69de29 diff --git a/packages/react-app/src/components/index.js b/packages/react-app/src/components/index.js index de594b8..7d6764c 100644 --- a/packages/react-app/src/components/index.js +++ b/packages/react-app/src/components/index.js @@ -1,3 +1,6 @@ export {default as Loader} from './Loader'; export {default as Exchange} from './Exchange'; -export {default as WalletButton} from './WalletButton'; \ No newline at end of file +export {default as WalletButton} from './WalletButton'; +export { default as AmountIn } from "./AmountIn"; +export { default as AmountOut } from "./AmountOut"; +export { default as Balance } from "./Balance"; \ No newline at end of file From 3c0473232f7626c5c761ec4c2e88d53dae7d1cb6 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 12:47:05 +0100 Subject: [PATCH 02/18] Update AmountIn.js --- packages/react-app/src/components/AmountIn.js | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index 8b13789..a3e8221 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -1 +1,24 @@ +import React, { useState, useEffect, useRef } from "react"; + +import { chevronDown } from "../assets"; // icon +import { useOnClickOutside } from "../utils"; //helps to close menu bar +import styles from "../styles"; + +const AmountIn = () => { + return( +
+ typeof onChange === "function" && onChange(e.target.value)} + className={styles.amountInput} + /> +
+ ) +} + + + From 9e6079083da7932e60171e5de200ffe56340e5b5 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 12:54:48 +0100 Subject: [PATCH 03/18] Update AmountIn.js --- packages/react-app/src/components/AmountIn.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index a3e8221..132d406 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -15,6 +15,18 @@ const AmountIn = () => { onChange={(e) => typeof onChange === "function" && onChange(e.target.value)} className={styles.amountInput} /> +
setShowList(!showList)}> + +
) } From fb8fa8fe49d161aad4a59e0f6d64b45d62e066c1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 12:56:53 +0100 Subject: [PATCH 04/18] Update AmountIn.js --- packages/react-app/src/components/AmountIn.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index 132d406..61c210a 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -5,6 +5,9 @@ import { useOnClickOutside } from "../utils"; //helps to close menu bar import styles from "../styles"; const AmountIn = () => { + const [showList, setShowList] = useState(false); + + return(
{ }`} /> -
+ ) } From 2fef1c09c5d14cc058bd7112f8c938784065ff32 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 12:57:22 +0100 Subject: [PATCH 05/18] Update AmountIn.js --- packages/react-app/src/components/AmountIn.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index 61c210a..03f2109 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -29,6 +29,10 @@ const AmountIn = () => { }`} /> + + {showList && ( + + ) From ebc1a7914aa3b5d5da7262a2c66539f4ca3dcb3a Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:02:18 +0100 Subject: [PATCH 06/18] Update AmountIn.js --- packages/react-app/src/components/AmountIn.js | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index 03f2109..aeca9d6 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -6,7 +6,16 @@ import styles from "../styles"; const AmountIn = () => { const [showList, setShowList] = useState(false); + const [activeCurrency, setActiveCurrency] = useState("Select"); + const ref = useRef() + + useOnClickOutside(ref, () => setShowList(false)) + useEffect(() => { + if (Object.keys(currencies).includes(currencyValue)) + setActiveCurrency(currencies[currencyValue]); + else setActiveCurrency("Select"); + }, [currencies, currencyValue]); return(
@@ -31,6 +40,24 @@ const AmountIn = () => { {showList && ( +
    + {Object.entries(currencies).map(([token, tokenName], index) => ( +
  • { + if (typeof onSelect === "function") onSelect(token); + setActiveCurrency(tokenName); + setShowList(false); + }} + > + {tokenName} +
  • + ))} +
+ )}
From bd0b4c969b247bea632adfe904a4994928f1a657 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:06:56 +0100 Subject: [PATCH 07/18] AmountIn/Out/Balance --- packages/react-app/src/components/AmountIn.js | 2 +- .../react-app/src/components/AmountOut.js | 67 +++++++++++++++++++ packages/react-app/src/components/Balance.js | 24 +++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index aeca9d6..da8d4bf 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -8,7 +8,7 @@ const AmountIn = () => { const [showList, setShowList] = useState(false); const [activeCurrency, setActiveCurrency] = useState("Select"); const ref = useRef() - + useOnClickOutside(ref, () => setShowList(false)) useEffect(() => { diff --git a/packages/react-app/src/components/AmountOut.js b/packages/react-app/src/components/AmountOut.js index e69de29..698b621 100644 --- a/packages/react-app/src/components/AmountOut.js +++ b/packages/react-app/src/components/AmountOut.js @@ -0,0 +1,67 @@ +import React, { useState, useEffect, useRef } from "react"; +import { formatUnits } from "ethers/lib/utils"; + +import { chevronDown } from "../assets"; +import { useAmountsOut, useOnClickOutside } from "../utils"; +import styles from "../styles"; + +const AmountOut = ({ fromToken, toToken, amountIn, pairContract, currencyValue, onSelect, currencies }) => { + const [showList, setShowList] = useState(false); + const [activeCurrency, setActiveCurrency] = useState("Select"); + const ref = useRef() + + const amountOut = useAmountsOut(pairContract, amountIn, fromToken, toToken) ?? 0; + + useOnClickOutside(ref, () => setShowList(false)) + + useEffect(() => { + if (Object.keys(currencies).includes(currencyValue)) { + setActiveCurrency(currencies[currencyValue]); + } else { + setActiveCurrency("Select") + } + }, [currencyValue, currencies]); + + return ( +
+ + +
setShowList(!showList)}> + + + {showList && ( +
    + {Object.entries(currencies).map(([token, tokenName], index) => ( +
  • { + if (typeof onSelect === "function") onSelect(token); + setActiveCurrency(tokenName); + setShowList(false); + }} + > + {tokenName} +
  • + ))} +
+ )} +
+
+ ); +}; + +export default AmountOut; diff --git a/packages/react-app/src/components/Balance.js b/packages/react-app/src/components/Balance.js index e69de29..dacba32 100644 --- a/packages/react-app/src/components/Balance.js +++ b/packages/react-app/src/components/Balance.js @@ -0,0 +1,24 @@ +import React from "react"; +import { formatUnits, parseUnits } from "ethers/lib/utils"; + +import styles from "../styles"; + +const Balance = ({ tokenBalance }) => { + + return ( +
+

+ {tokenBalance ? ( + <> + Balance: + {formatUnits(tokenBalance ?? parseUnits("0"))} + + ) : ( + "" + )} +

+
+ ); +}; + +export default Balance; From c3ee6e7a1499c6a4e049808981c0f50e51b32552 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:10:21 +0100 Subject: [PATCH 08/18] Update Exchange.js --- packages/react-app/src/components/Exchange.js | 76 ++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/packages/react-app/src/components/Exchange.js b/packages/react-app/src/components/Exchange.js index 07da0ba..7c5c4f7 100644 --- a/packages/react-app/src/components/Exchange.js +++ b/packages/react-app/src/components/Exchange.js @@ -5,12 +5,84 @@ import { ERC20, useContractFunction, useEthers, useTokenAllowance, useTokenBalan import { ethers } from "ethers"; import { parseUnits } from "ethers/lib/utils"; +import { getAvailableTokens, getCounterpartTokens, findPoolByTokens, isOperationPending, getFailureMessage, getSuccessMessage } from '../utils'; import { ROUTER_ADDRESS } from "../config"; +import AmountIn from "./"; +import AmountOut from "./"; +import Balance from "./"; +import styles from "../styles"; const Exchange = ({ pools }) => { + const isApproving = isOperationPending(swapApproveState); + const isSwapping = isOperationPending(swapExecuteState); + + const successMessage = getSuccessMessage(swapApproveState, swapExecuteState); + const failureMessage = getFailureMessage(swapApproveState, swapExecuteState); + return ( -
Exchange
- ) +
+
+ + +
+ +
+ + +
+ + {approvedNeeded && !isSwapping ? ( + + ) : ( + + )} + + {failureMessage && !resetState ? ( +

{failureMessage}

+ ) : successMessage ? ( +

{successMessage}

+ ) : ( + "" + )} +
+ ); } export default Exchange; \ No newline at end of file From db65a242ba9ccc7fa39522822f8510d8895f4aed Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:23:29 +0100 Subject: [PATCH 09/18] Update Exchange.js --- packages/react-app/src/components/Exchange.js | 120 +++++++++--------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/packages/react-app/src/components/Exchange.js b/packages/react-app/src/components/Exchange.js index 7c5c4f7..5279ac0 100644 --- a/packages/react-app/src/components/Exchange.js +++ b/packages/react-app/src/components/Exchange.js @@ -21,66 +21,66 @@ const Exchange = ({ pools }) => { return (
-
- - -
- -
- - -
- - {approvedNeeded && !isSwapping ? ( - - ) : ( - - )} - - {failureMessage && !resetState ? ( -

{failureMessage}

- ) : successMessage ? ( -

{successMessage}

- ) : ( - "" - )} +
+ + +
+ +
+ + +
+ + {approvedNeeded && !isSwapping ? ( + + ) : ( + + )} + + {failureMessage && !resetState ? ( +

{failureMessage}

+ ) : successMessage ? ( +

{successMessage}

+ ) : ( + "" + )}
); } From 429646f883f497e2ee13070df7f76c3c21c20c58 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:23:33 +0100 Subject: [PATCH 10/18] Update AmountIn.js --- packages/react-app/src/components/AmountIn.js | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index da8d4bf..9de20ba 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -19,49 +19,48 @@ const AmountIn = () => { return(
- typeof onChange === "function" && onChange(e.target.value)} - className={styles.amountInput} + typeof onChange === "function" && onChange(e.target.value)} + className={styles.amountInput} + /> + +
setShowList(!showList)}> + - - {showList && ( -
    - {Object.entries(currencies).map(([token, tokenName], index) => ( -
  • { - if (typeof onSelect === "function") onSelect(token); - setActiveCurrency(tokenName); - setShowList(false); - }} - > - {tokenName} -
  • - ))} -
- )} - - -
+ + + {showList && ( +
    + {Object.entries(currencies).map(([token, tokenName], index) => ( +
  • { + if (typeof onSelect === "function") onSelect(token); + setActiveCurrency(tokenName); + setShowList(false); + }} + > + {tokenName} +
  • + ))} +
+ )}
+ ) } From 0d96c0e3f002ab4d906f318f3c79c67ebeb0b993 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:23:47 +0100 Subject: [PATCH 11/18] Update Exchange.js --- packages/react-app/src/components/Exchange.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/react-app/src/components/Exchange.js b/packages/react-app/src/components/Exchange.js index 5279ac0..19a09d2 100644 --- a/packages/react-app/src/components/Exchange.js +++ b/packages/react-app/src/components/Exchange.js @@ -13,6 +13,9 @@ import Balance from "./"; import styles from "../styles"; const Exchange = ({ pools }) => { + const { account } = useEthers(); + + const isApproving = isOperationPending(swapApproveState); const isSwapping = isOperationPending(swapExecuteState); From 4b8627c456d1687368fac88e91656ab8439b96b7 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:27:03 +0100 Subject: [PATCH 12/18] Update Exchange.js --- packages/react-app/src/components/Exchange.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/react-app/src/components/Exchange.js b/packages/react-app/src/components/Exchange.js index 19a09d2..1aa0797 100644 --- a/packages/react-app/src/components/Exchange.js +++ b/packages/react-app/src/components/Exchange.js @@ -14,6 +14,16 @@ import styles from "../styles"; const Exchange = ({ pools }) => { const { account } = useEthers(); + const [fromValue, setFromValue] = useState("0"); + const [fromToken, setFromToken] = useState(pools[0].token0Address); + const [toToken, setToToken] = useState(""); + const [resetState, setResetState] = useState(false) + + const fromValueBigNumber = parseUnits(fromValue || "0"); + const availableTokens = getAvailableTokens(pools); //What tokens can we swap from? + const counterpartTokens = getCounterpartTokens(pools, fromToken); //What tokens can we swap to? + const pairAddress = findPoolByTokens(pools, fromToken, toToken)?.address ?? ""; //find a pair address ot that liquidity pair + const isApproving = isOperationPending(swapApproveState); From 3d6af9251e36a431065e0e82d546990e9471c192 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:27:57 +0100 Subject: [PATCH 13/18] Update Exchange.js --- packages/react-app/src/components/Exchange.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react-app/src/components/Exchange.js b/packages/react-app/src/components/Exchange.js index 1aa0797..f93bf3f 100644 --- a/packages/react-app/src/components/Exchange.js +++ b/packages/react-app/src/components/Exchange.js @@ -24,7 +24,11 @@ const Exchange = ({ pools }) => { const counterpartTokens = getCounterpartTokens(pools, fromToken); //What tokens can we swap to? const pairAddress = findPoolByTokens(pools, fromToken, toToken)?.address ?? ""; //find a pair address ot that liquidity pair - + //Get contract addresses + const routerContract = new Contract(ROUTER_ADDRESS, abis.router02); + const fromTokenContract = new Contract(fromToken, ERC20.abi); + const fromTokenBalance = useTokenBalance(fromToken, account); //Know balance of "from Token" + const toTokenBalance = useTokenBalance(toToken, account); //Know balance of "to Token" const isApproving = isOperationPending(swapApproveState); const isSwapping = isOperationPending(swapExecuteState); From 3ecfaa3908381adc0df83197648aa4d285476cf7 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 13:32:22 +0100 Subject: [PATCH 14/18] Update Exchange.js added const --- packages/react-app/src/components/Exchange.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/react-app/src/components/Exchange.js b/packages/react-app/src/components/Exchange.js index f93bf3f..bc514e3 100644 --- a/packages/react-app/src/components/Exchange.js +++ b/packages/react-app/src/components/Exchange.js @@ -29,6 +29,10 @@ const Exchange = ({ pools }) => { const fromTokenContract = new Contract(fromToken, ERC20.abi); const fromTokenBalance = useTokenBalance(fromToken, account); //Know balance of "from Token" const toTokenBalance = useTokenBalance(toToken, account); //Know balance of "to Token" + const tokenAllowance = useTokenAllowance(fromToken, account, ROUTER_ADDRESS) || parseUnits("0"); + const approvedNeeded = fromValueBigNumber.gt(tokenAllowance); //We need to approve to make the swap + const formValueIsGreaterThan0 = fromValueBigNumber.gt(parseUnits("0")); //has to be greater than 0 + const hasEnoughBalance = fromValueBigNumber.lte(fromTokenBalance ?? parseUnits("0")); //lte = lower than or equal to const isApproving = isOperationPending(swapApproveState); const isSwapping = isOperationPending(swapExecuteState); From da3c8798be1234d1d2a324a7e54a3bed9e33d5a4 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 15:24:19 +0100 Subject: [PATCH 15/18] Finish Exchange.js --- packages/react-app/src/components/Exchange.js | 240 +++++++++++------- packages/react-app/src/components/Loader.js | 6 +- 2 files changed, 154 insertions(+), 92 deletions(-) diff --git a/packages/react-app/src/components/Exchange.js b/packages/react-app/src/components/Exchange.js index bc514e3..548218d 100644 --- a/packages/react-app/src/components/Exchange.js +++ b/packages/react-app/src/components/Exchange.js @@ -7,103 +7,161 @@ import { parseUnits } from "ethers/lib/utils"; import { getAvailableTokens, getCounterpartTokens, findPoolByTokens, isOperationPending, getFailureMessage, getSuccessMessage } from '../utils'; import { ROUTER_ADDRESS } from "../config"; -import AmountIn from "./"; -import AmountOut from "./"; -import Balance from "./"; +import AmountIn from "./AmountIn"; +import AmountOut from "./AmountOut"; +import Balance from "./Balance"; import styles from "../styles"; const Exchange = ({ pools }) => { - const { account } = useEthers(); - const [fromValue, setFromValue] = useState("0"); - const [fromToken, setFromToken] = useState(pools[0].token0Address); - const [toToken, setToToken] = useState(""); - const [resetState, setResetState] = useState(false) + const { account } = useEthers(); + const [fromValue, setFromValue] = useState("0"); + const [fromToken, setFromToken] = useState(pools[0].token0Address); // initialFromToken + const [toToken, setToToken] = useState(""); + const [resetState, setResetState] = useState(false) - const fromValueBigNumber = parseUnits(fromValue || "0"); - const availableTokens = getAvailableTokens(pools); //What tokens can we swap from? - const counterpartTokens = getCounterpartTokens(pools, fromToken); //What tokens can we swap to? - const pairAddress = findPoolByTokens(pools, fromToken, toToken)?.address ?? ""; //find a pair address ot that liquidity pair + const fromValueBigNumber = parseUnits(fromValue || "0"); // converse the string to bigNumber + const availableTokens = getAvailableTokens(pools); + const counterpartTokens = getCounterpartTokens(pools, fromToken); + const pairAddress = findPoolByTokens(pools, fromToken, toToken)?.address ?? ""; - //Get contract addresses - const routerContract = new Contract(ROUTER_ADDRESS, abis.router02); - const fromTokenContract = new Contract(fromToken, ERC20.abi); - const fromTokenBalance = useTokenBalance(fromToken, account); //Know balance of "from Token" - const toTokenBalance = useTokenBalance(toToken, account); //Know balance of "to Token" - const tokenAllowance = useTokenAllowance(fromToken, account, ROUTER_ADDRESS) || parseUnits("0"); - const approvedNeeded = fromValueBigNumber.gt(tokenAllowance); //We need to approve to make the swap - const formValueIsGreaterThan0 = fromValueBigNumber.gt(parseUnits("0")); //has to be greater than 0 - const hasEnoughBalance = fromValueBigNumber.lte(fromTokenBalance ?? parseUnits("0")); //lte = lower than or equal to + const routerContract = new Contract(ROUTER_ADDRESS, abis.router02); + const fromTokenContract = new Contract(fromToken, ERC20.abi); + const fromTokenBalance = useTokenBalance(fromToken, account); + const toTokenBalance = useTokenBalance(toToken, account); + const tokenAllowance = useTokenAllowance(fromToken, account, ROUTER_ADDRESS) || parseUnits("0"); + const approvedNeeded = fromValueBigNumber.gt(tokenAllowance); + const formValueIsGreaterThan0 = fromValueBigNumber.gt(parseUnits("0")); + const hasEnoughBalance = fromValueBigNumber.lte(fromTokenBalance ?? parseUnits("0")); - const isApproving = isOperationPending(swapApproveState); - const isSwapping = isOperationPending(swapExecuteState); + // approve initiating a contract call (similar to use state) -> gives the state and the sender... + const { state: swapApproveState, send: swapApproveSend } = + useContractFunction(fromTokenContract, "approve", { + transactionName: "onApproveRequested", + gasLimitBufferPercentage: 10, + }); + // swap initiating a contract call (similar to use state) -> gives the state and the sender... + const { state: swapExecuteState, send: swapExecuteSend } = + useContractFunction(routerContract, "swapExactTokensForTokens", { + transactionName: "swapExactTokensForTokens", + gasLimitBufferPercentage: 10, + }); - const successMessage = getSuccessMessage(swapApproveState, swapExecuteState); - const failureMessage = getFailureMessage(swapApproveState, swapExecuteState); + const isApproving = isOperationPending(swapApproveState); + const isSwapping = isOperationPending(swapExecuteState); + const canApprove = !isApproving && approvedNeeded; + const canSwap = !approvedNeeded && !isSwapping && formValueIsGreaterThan0 && hasEnoughBalance; - return ( -
-
- - -
- -
- - -
- - {approvedNeeded && !isSwapping ? ( - - ) : ( - - )} - - {failureMessage && !resetState ? ( -

{failureMessage}

- ) : successMessage ? ( -

{successMessage}

- ) : ( - "" - )} -
- ); -} + const successMessage = getSuccessMessage(swapApproveState, swapExecuteState); + const failureMessage = getFailureMessage(swapApproveState, swapExecuteState); -export default Exchange; \ No newline at end of file + const onApproveRequested = () => { + swapApproveSend(ROUTER_ADDRESS, ethers.constants.MaxUint256); + }; + + // https://docs.uniswap.org/protocol/V2/reference/smart-contracts/router-02#swapexacttokensfortokens + const onSwapRequested = () => { + swapExecuteSend( + fromValueBigNumber, + 0, + [fromToken, toToken], + account, + Math.floor(Date.now() / 1000) + 60 * 20 + ).then((_) => { + setFromValue("0"); + }); + }; + + const onFromValueChange = (value) => { + const trimmedValue = value.trim(); + + try { + trimmedValue && parseUnits(value); + setFromValue(value); + } catch (e) {} + }; + + const onFromTokenChange = (value) => { + setFromToken(value); + }; + + const onToTokenChange = (value) => { + setToToken(value); + }; + + useEffect(() => { + if(failureMessage || successMessage) { + setTimeout(() => { + setResetState(true) + setFromValue("0") + setToToken("") + }, 5000) + } + }, [failureMessage, successMessage]) + + return ( +
+
+ + +
+ +
+ + +
+ + {approvedNeeded && !isSwapping ? ( + + ) : ( + + )} + + {failureMessage && !resetState ? ( +

{failureMessage}

+ ) : successMessage ? ( +

{successMessage}

+ ) : ( + "" + )} +
+ ); +}; + +export default Exchange; diff --git a/packages/react-app/src/components/Loader.js b/packages/react-app/src/components/Loader.js index a41289d..b195bc5 100644 --- a/packages/react-app/src/components/Loader.js +++ b/packages/react-app/src/components/Loader.js @@ -6,7 +6,11 @@ import {ethereumLogo2 } from "../assets"; const Loader = ({ title }) => { return (
- Ethereum Logo + Ethereum Logo

{title}

From b172fc84a57154b75a1f6cc1cbaa2a9181793e5e Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 15:26:07 +0100 Subject: [PATCH 16/18] Update AmountIn.js --- packages/react-app/src/components/AmountIn.js | 118 +++++++++--------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/packages/react-app/src/components/AmountIn.js b/packages/react-app/src/components/AmountIn.js index 9de20ba..d35be5c 100644 --- a/packages/react-app/src/components/AmountIn.js +++ b/packages/react-app/src/components/AmountIn.js @@ -1,69 +1,67 @@ import React, { useState, useEffect, useRef } from "react"; -import { chevronDown } from "../assets"; // icon -import { useOnClickOutside } from "../utils"; //helps to close menu bar +import { chevronDown } from "../assets"; +import { useOnClickOutside } from "../utils"; import styles from "../styles"; -const AmountIn = () => { - const [showList, setShowList] = useState(false); - const [activeCurrency, setActiveCurrency] = useState("Select"); - const ref = useRef() +const AmountIn = ({ value, onChange, currencyValue, onSelect, currencies, isSwapping }) => { + const [showList, setShowList] = useState(false); + const [activeCurrency, setActiveCurrency] = useState("Select"); + const ref = useRef() - useOnClickOutside(ref, () => setShowList(false)) + useOnClickOutside(ref, () => setShowList(false)) - useEffect(() => { - if (Object.keys(currencies).includes(currencyValue)) - setActiveCurrency(currencies[currencyValue]); - else setActiveCurrency("Select"); - }, [currencies, currencyValue]); + useEffect(() => { + if (Object.keys(currencies).includes(currencyValue)) + setActiveCurrency(currencies[currencyValue]); + else setActiveCurrency("Select"); + }, [currencies, currencyValue]); - return( -
- typeof onChange === "function" && onChange(e.target.value)} - className={styles.amountInput} - /> - -
setShowList(!showList)}> - - - {showList && ( -
    - {Object.entries(currencies).map(([token, tokenName], index) => ( -
  • { - if (typeof onSelect === "function") onSelect(token); - setActiveCurrency(tokenName); - setShowList(false); - }} - > - {tokenName} -
  • - ))} -
- )} -
+ return ( +
+ typeof onChange === "function" && onChange(e.target.value)} + className={styles.amountInput} + /> + +
setShowList(!showList)}> + + + {showList && ( +
    + {Object.entries(currencies).map(([token, tokenName], index) => ( +
  • { + if (typeof onSelect === "function") onSelect(token); + setActiveCurrency(tokenName); + setShowList(false); + }} + > + {tokenName} +
  • + ))} +
+ )}
- ) -} - - - +
+ ); +}; +export default AmountIn; From 83c846ae8a35c1d72f167a50dd76b12be5cf5e31 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 15:26:09 +0100 Subject: [PATCH 17/18] Update AmountOut.js --- .../react-app/src/components/AmountOut.js | 100 +++++++++--------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/packages/react-app/src/components/AmountOut.js b/packages/react-app/src/components/AmountOut.js index 698b621..6fdf1bb 100644 --- a/packages/react-app/src/components/AmountOut.js +++ b/packages/react-app/src/components/AmountOut.js @@ -6,62 +6,62 @@ import { useAmountsOut, useOnClickOutside } from "../utils"; import styles from "../styles"; const AmountOut = ({ fromToken, toToken, amountIn, pairContract, currencyValue, onSelect, currencies }) => { - const [showList, setShowList] = useState(false); - const [activeCurrency, setActiveCurrency] = useState("Select"); - const ref = useRef() + const [showList, setShowList] = useState(false); + const [activeCurrency, setActiveCurrency] = useState("Select"); + const ref = useRef() - const amountOut = useAmountsOut(pairContract, amountIn, fromToken, toToken) ?? 0; + const amountOut = useAmountsOut(pairContract, amountIn, fromToken, toToken) ?? 0; - useOnClickOutside(ref, () => setShowList(false)) + useOnClickOutside(ref, () => setShowList(false)) - useEffect(() => { - if (Object.keys(currencies).includes(currencyValue)) { - setActiveCurrency(currencies[currencyValue]); - } else { - setActiveCurrency("Select") - } - }, [currencyValue, currencies]); + useEffect(() => { + if (Object.keys(currencies).includes(currencyValue)) { + setActiveCurrency(currencies[currencyValue]); + } else { + setActiveCurrency("Select") + } + }, [currencyValue, currencies]); - return ( -
- + return ( +
+ -
setShowList(!showList)}> - +
setShowList(!showList)}> + - {showList && ( -
    - {Object.entries(currencies).map(([token, tokenName], index) => ( -
  • { - if (typeof onSelect === "function") onSelect(token); - setActiveCurrency(tokenName); - setShowList(false); - }} - > - {tokenName} -
  • - ))} -
- )} -
-
- ); + {showList && ( +
    + {Object.entries(currencies).map(([token, tokenName], index) => ( +
  • { + if (typeof onSelect === "function") onSelect(token); + setActiveCurrency(tokenName); + setShowList(false); + }} + > + {tokenName} +
  • + ))} +
+ )} +
+
+ ); }; export default AmountOut; From 32f20782a66e8db5c55298672154721cff4bed31 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 5 Nov 2022 15:29:16 +0100 Subject: [PATCH 18/18] Update App.js --- packages/react-app/src/App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-app/src/App.js b/packages/react-app/src/App.js index 42d47f3..4b7e7a2 100644 --- a/packages/react-app/src/App.js +++ b/packages/react-app/src/App.js @@ -1,8 +1,8 @@ import React from "react" import { useEthers } from "@usedapp/core"; -import { usePools } from "./hooks"; import styles from './styles'; +import { usePools } from "./hooks"; import { fhtLogo } from './assets'; import { Exchange, Loader, WalletButton } from "./components";