react-router-dom#useSearchParams JavaScript Examples

The following examples show how to use react-router-dom#useSearchParams. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
LiquidityNew = (props) => {
  const { activeTab, tokenIn, setTokenIn, tokenOut, setTokenOut, setActiveTab } =
    useLocationStateInLiquidity();

  const [searchQuery, setSearchQuery] = useState('');
  const [swapData, setSwapData] = useState({});
  const [tokenType, setTokenType] = useState('tokenIn');
  const [show, setShow] = useState(false);
  const [slippage, setSlippage] = useState(0.5);
  const [recepient, setRecepient] = useState('');
  const [tokenContractInstances, setTokenContractInstances] = useState({});
  const [showConfirmAddSupply, setShowConfirmAddSupply] = useState(false);
  const [showConfirmRemoveSupply, setShowConfirmRemoveSupply] = useState(false);
  const [showConfirmTransaction, setShowConfirmTransaction] = useState(false);
  const [loaderMessage, setLoaderMessage] = useState({});
  const [loaderInButton, setLoaderInButton] = useState(false);
  const [loading, setLoading] = useState(false);
  const [getTokenPrice, setGetTokenPrice] = useState({});
  const [userBalances, setUserBalances] = useState({});

  const location = useLocation();
  const navigate = useNavigate();
  const { pathname } = location;
  const splitLocation = pathname.split('/');
  const [searchParams] = useSearchParams();
  const [isLiquidityPosition, setLiquidityPosition] = useState(false);
  const [positionDetails, setPositionDetails] = useState({});
  const [isPositionAvailable, setPositionAvailable] = useState(false);

  const [balanceUpdate, setBalanceUpdate] = useState(false);

  useEffect(async () => {
    const isStable = isTokenPairStable(tokenIn.name, tokenOut.name);

    const ress = await getLpTokenBalanceForPair(tokenIn.name, tokenOut.name, props.walletAddress);

    setPositionAvailable(ress.isLiquidityAvailable);
    if (ress.isLiquidityAvailable) {
      let res;
      if (isStable) {
        if (CONFIG.AMM[CONFIG.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name]?.type === 'xtz') {
          res = await getLiquidityPositionDetailsStable(
            tokenIn.name,
            tokenOut.name,
            props.walletAddress,
          );
        } else if (
          CONFIG.AMM[CONFIG.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name]?.type === 'veStableAMM'
        ) {
          res = await getLiquidityPositionDetails(tokenIn.name, tokenOut.name, props.walletAddress);
        }
      } else {
        res = await getLiquidityPositionDetails(tokenIn.name, tokenOut.name, props.walletAddress);
      }

      setPositionDetails(res);
    }
  }, [tokenIn, tokenOut, props]);

  useEffect(() => {
    setLoaderInButton(true);

    getTokenPrices().then((tokenPrice) => {
      setGetTokenPrice(tokenPrice);
    });
  }, []);

  const activeKey = useMemo(() => {
    if (location.pathname === '/liquidity/remove') {
      return 'remove';
    }

    return 'add';
  }, [location.pathname]);
  useEffect(() => {
    if (!location.pathname.includes('liquidityPositions')) {
      setLiquidityPosition(false);
    }
  }, [searchParams]);

  const handleClose = () => {
    setShow(false);

    setShowConfirmAddSupply(false);
    setShowConfirmRemoveSupply(false);
    setShowConfirmTransaction(false);
    setSearchQuery('');
  };

  useEffect(() => {
    const updateBalance = async () => {
      if (props.walletAddress) {
        setTokenContractInstances({});

        const tzBTCName = 'tzBTC';
        const balancePromises = [];

        tokenIn.name === tzBTCName
          ? balancePromises.push(fetchtzBTCBalance(props.walletAddress))
          : balancePromises.push(
              config.AMM[config.NETWORK][tokenIn.name]?.DEX_PAIRS[tokenOut.name]?.type === 'xtz'
                ? getUserBalanceByRpcStable(tokenIn.name, props.walletAddress)
                : getUserBalanceByRpc(tokenIn.name, props.walletAddress),
            );

        tokenOut.name === tzBTCName
          ? balancePromises.push(fetchtzBTCBalance(props.walletAddress))
          : balancePromises.push(
              config.AMM[config.NETWORK][tokenIn.name]?.DEX_PAIRS[tokenOut.name]?.type === 'xtz'
                ? getUserBalanceByRpcStable(tokenOut.name, props.walletAddress)
                : getUserBalanceByRpc(tokenOut.name, props.walletAddress),
            );

        if (
          config.AMM[config.NETWORK][tokenIn.name]?.DEX_PAIRS[tokenOut.name]?.type === 'xtz'
            ? config.STABLESWAP[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name]
            : config.AMM[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name]
        ) {
          const lpToken = isTokenPairStable(tokenIn.name, tokenOut.name)
            ? config.STABLESWAP[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name]
                .liquidityToken
            : config.AMM[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name].liquidityToken;

          balancePromises.push(
            config.AMM[config.NETWORK][tokenIn.name]?.DEX_PAIRS[tokenOut.name]?.type === 'xtz'
              ? getUserBalanceByRpcStable(lpToken, props.walletAddress)
              : getUserBalanceByRpc(lpToken, props.walletAddress),
          );
        }
        const balanceResponse = await Promise.all(balancePromises);

        setUserBalances((prev) => ({
          ...prev,
          ...balanceResponse.reduce(
            (acc, cur) => ({
              ...acc,
              [cur.identifier]: cur.balance,
            }),
            {},
          ),
        }));
      }
    };
    updateBalance();
  }, [tokenIn, tokenOut, props, balanceUpdate]);

  const selectToken = (token) => {
    setLoaderInButton(true);

    setSwapData({});

    if (tokenType === 'tokenIn') {
      setTokenIn({
        name: token.name,
        image: token.image,
      });

      if (token.name === 'tez') {
        setTokenOut({
          name: 'ctez',
          image: ctez,
        });
      } else if (token.name === 'EURL') {
        setTokenOut({
          name: 'agEUR.e',
          image: ageure,
        });
      } else if (token.name === 'agEUR.e') {
        setTokenOut({
          name: 'EURL',
          image: eurl,
        });
      }
    } else {
      setTokenOut({
        name: token.name,
        image: token.image,
      });
    }
    handleClose();
  };

  useEffect(() => {
    if (activeTab === 'liquidity') {
      if (
        Object.prototype.hasOwnProperty.call(tokenIn, 'name') &&
        Object.prototype.hasOwnProperty.call(tokenOut, 'name')
      ) {
        const pairExists = isTokenPairStable(tokenIn.name, tokenOut.name)
          ? !!config.STABLESWAP[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name]
          : !!config.AMM[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name];

        if (pairExists) {
          if (config.AMM[config.NETWORK][tokenIn.name]?.DEX_PAIRS[tokenOut.name]?.type === 'xtz') {
            loadSwapDataStable(tokenIn.name, tokenOut.name).then((data) => {
              if (data.success) {
                setSwapData(data);

                setLoaderInButton(false);
              }
            });
          } else if (
            config.AMM[config.NETWORK][tokenIn.name]?.DEX_PAIRS[tokenOut.name]?.type ===
            'veStableAMM'
          ) {
            loadSwapDataGeneralStable(tokenIn.name, tokenOut.name).then((data) => {
              if (data.success) {
                setSwapData(data);

                setLoaderInButton(false);
              }
            });
          } else {
            loadSwapData(tokenIn.name, tokenOut.name).then((data) => {
              if (data.success) {
                setSwapData(data);

                setLoaderInButton(false);
              }
            });
          }
        }
      }
    }
  }, [tokenIn, tokenOut, activeTab, splitLocation[1]]);

  const handleTokenType = (type) => {
    setBalanceUpdate(false);
    setShow(true);
    setTokenType(type);
    setLoading(false);
  };

  const fetchUserWalletBalance = () => {
    setLoaderInButton(true);
  };

  const handleLoaderMessage = (type, message) => {
    setLoaderMessage({
      type: type,
      message: message,
    });
    setLoading(false);
  };

  const resetAllValues = () => {
    setRecepient('');
    setTokenType('tokenIn');
  };

  const changeLiquidityType = (tab) => {
    const tokenAFromParam = searchParams.get('tokenA');
    const tokenBFromParam = searchParams.get('tokenB');
    navigate({
      pathname: `/liquidity/${tab}`,
      search: `?${createSearchParams({
        ...(tokenAFromParam ? { tokenA: tokenAFromParam } : {}),
        ...(tokenBFromParam ? { tokenB: tokenBFromParam } : {}),
      })}`,
    });
  };
  const redirectLiquidityPositions = (value) => {
    setLiquidityPosition(value);

    value ? setActiveTab('liquidityPositions') : setActiveTab('liquidity');
  };

  useEffect(() => {
    const tokenAFromParam = searchParams.get('tokenA');
    const tokenBFromParam = searchParams.get('tokenB');

    if (tokenAFromParam !== tokenBFromParam) {
      if (tokenAFromParam) {
        liquidityTokens.map((token) => {
          if (token.name === tokenAFromParam) {
            setTokenIn({
              name: tokenAFromParam,
              image: token.image,
            });
          }
        });
      }

      if (tokenBFromParam) {
        liquidityTokens.map((token) => {
          if (token.name === tokenBFromParam) {
            setTokenOut({
              name: tokenBFromParam,
              image: token.image,
            });
          }
        });
      }
    }
  }, [searchParams]);

  return (
    <Container fluid className="removing-padding">
      {props.walletAddress && (
        <p
          className="redirect-label-lp"
          style={{ cursor: 'pointer' }}
          onClick={() => redirectLiquidityPositions(!isLiquidityPosition)}
        >
          {isLiquidityPosition && (
            <span className={clsx('material-icons', 'arrow-forward', 'mt-1', 'ml-0')}>
              arrow_back_ios_icon
            </span>
          )}
          {isLiquidityPosition ? 'Back' : 'View Liquidity Positions'}
          {!isLiquidityPosition && (
            <span className={clsx('material-icons', 'arrow-forward', 'mt-1')}>
              arrow_forward_ios_icon
            </span>
          )}
        </p>
      )}
      {isLiquidityPosition && <div className="liq-label">Position overview</div>}

      {!isLiquidityPosition ? (
        <Col
          sm={8}
          md={6}
          className={clsx('liquidity-content-container', !props.walletAddress && 'liq-margin')}
        >
          <div className="">
            <Tabs
              activeKey={activeKey}
              className="liq-container-tab"
              onSelect={(e) => changeLiquidityType(e)}
              mountOnEnter={true}
              unmountOnExit={true}
            >
              <Tab eventKey="add" title="Add">
                <AddLiquidity
                  walletAddress={props.walletAddress}
                  connecthWallet={props.connecthWallet}
                  tokenIn={tokenIn}
                  tokenOut={tokenOut}
                  handleTokenType={handleTokenType}
                  swapData={swapData}
                  userBalances={userBalances}
                  tokenContractInstances={tokenContractInstances}
                  getTokenPrice={getTokenPrice}
                  setSlippage={setSlippage}
                  setRecepient={setRecepient}
                  recepient={recepient}
                  slippage={slippage}
                  loading={loading}
                  setLoading={setLoading}
                  handleLoaderMessage={handleLoaderMessage}
                  loaderMessage={loaderMessage}
                  handleClose={handleClose}
                  showConfirmAddSupply={showConfirmAddSupply}
                  setShowConfirmAddSupply={setShowConfirmAddSupply}
                  showConfirmRemoveSupply={showConfirmRemoveSupply}
                  setShowConfirmRemoveSupply={setShowConfirmRemoveSupply}
                  setLoaderMessage={setLoaderMessage}
                  resetAllValues={resetAllValues}
                  fetchUserWalletBalance={fetchUserWalletBalance}
                  setTokenIn={setTokenIn}
                  setTokenOut={setTokenOut}
                  tokens={liquidityTokens}
                  loaderInButton={loaderInButton}
                  setLoaderInButton={setLoaderInButton}
                  setShowConfirmTransaction={setShowConfirmTransaction}
                  showConfirmTransaction={showConfirmTransaction}
                  positionDetails={positionDetails}
                  setPositionAvailable={setPositionAvailable}
                  isPositionAvailable={isPositionAvailable}
                  setPositionDetails={setPositionDetails}
                  theme={props.theme}
                  setBalanceUpdate={setBalanceUpdate}
                  balanceUpdate={balanceUpdate}
                  {...props}
                />
              </Tab>
              {/* {isPositionAvailable ? ( */}
              <Tab eventKey="remove" title="Remove">
                <RemoveLiquidity
                  theme={props.theme}
                  walletAddress={props.walletAddress}
                  connecthWallet={props.connecthWallet}
                  tokenIn={tokenIn}
                  tokenOut={tokenOut}
                  handleTokenType={handleTokenType}
                  swapData={swapData}
                  userBalances={userBalances}
                  tokenContractInstances={tokenContractInstances}
                  getTokenPrice={getTokenPrice}
                  setSlippage={setSlippage}
                  setRecepient={setRecepient}
                  recepient={recepient}
                  slippage={slippage}
                  loading={loading}
                  setLoading={setLoading}
                  handleLoaderMessage={handleLoaderMessage}
                  loaderMessage={loaderMessage}
                  handleClose={handleClose}
                  showConfirmAddSupply={showConfirmAddSupply}
                  setShowConfirmAddSupply={setShowConfirmAddSupply}
                  showConfirmRemoveSupply={showConfirmRemoveSupply}
                  setShowConfirmRemoveSupply={setShowConfirmRemoveSupply}
                  setLoaderMessage={setLoaderMessage}
                  resetAllValues={resetAllValues}
                  fetchUserWalletBalance={fetchUserWalletBalance}
                  setTokenIn={setTokenIn}
                  setTokenOut={setTokenOut}
                  tokens={liquidityTokens}
                  loaderInButton={loaderInButton}
                  setLoaderInButton={setLoaderInButton}
                  isStableSwap={isTokenPairStable(tokenIn.name, tokenOut.name)}
                  setShowConfirmTransaction={setShowConfirmTransaction}
                  showConfirmTransaction={showConfirmTransaction}
                  positionDetails={positionDetails}
                  setPositionAvailable={setPositionAvailable}
                  isPositionAvailable={isPositionAvailable}
                  setPositionDetails={setPositionDetails}
                />
              </Tab>
              {/* ) : null} */}
            </Tabs>
            <div className="settings-liq">
              <SettingsLiq
                slippage={slippage}
                setSlippage={setSlippage}
                walletAddress={props.walletAddress}
                theme={props.theme}
              />
            </div>
          </div>
        </Col>
      ) : (
        <LiquidityPositions walletAddress={props.walletAddress} theme={props.theme} />
      )}
      <LiquidityModal
        show={show}
        activeTab={activeTab}
        onHide={handleClose}
        selectToken={selectToken}
        tokens={liquidityTokens}
        tokenIn={tokenIn}
        tokenOut={tokenOut}
        tokenType={tokenType}
        searchQuery={searchQuery}
        setSearchQuery={setSearchQuery}
      />
    </Container>
  );
}
Example #2
Source File: useLocationStateInSwap.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
useLocationStateInSwap = () => {
  const [tokenParams, setTokenParams] = useSearchParams();
  const navigate = useNavigate();
  const location = useLocation();
  const [tokenIn, setTokenIn] = useState({
    name: 'ctez',
    image: ctez,
  });

  const [tokenOut, setTokenOut] = useState({});

  const AMMExists = useMemo(() => {
    return !!config.AMM[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name];
  }, [tokenIn, tokenOut]);

  const activeTab = useMemo(() => {
    if (location.pathname === '/swap') {
      return 'swap';
    }
  }, [location.pathname]);

  const paramKeys = useMemo(() => {
    if (activeTab === 'swap') {
      return { a: 'from', b: 'to' };
    }
  }, [activeTab]);

  const setActiveTab = (elem) => {
    if (elem) {
      navigate(`/${elem}`);

      if (elem === 'liquidity' && !AMMExists) {
        setTokenOut({});
      }
    }
  };

  useEffect(() => {
    setTokenParams(
      {
        ...(tokenIn.name ? { [paramKeys.a]: tokenIn.name } : {}),
        ...(tokenParams.get(paramKeys.b) ? { [paramKeys.b]: tokenParams.get(paramKeys.b) } : {}),
      },
      { replace: true },
    );
  }, [tokenIn]);

  useEffect(() => {
    setTokenParams(
      {
        ...(tokenParams.get(paramKeys.a) ? { [paramKeys.a]: tokenParams.get(paramKeys.a) } : {}),
        ...(tokenOut.name ? { [paramKeys.b]: tokenOut.name } : {}),
      },
      { replace: true },
    );
  }, [tokenOut]);

  useEffect(() => {
    const paramKey =
      location.pathname === '/swap' ? { a: 'from', b: 'to' } : { a: 'tokenA', b: 'tokenB' };

    const tokenInFromParam = tokenParams.get(paramKey.a);
    const tokenOutFromParam = tokenParams.get(paramKey.b);

    if (tokenInFromParam) {
      const tokenInDatum = tokens.find((token) => token.name === tokenInFromParam);

      if (tokenInDatum) {
        setTokenIn({
          name: tokenInDatum.name,
          image: tokenInDatum.image,
        });
      }
    }

    if (tokenOutFromParam) {
      const tokenOutDatum = tokens.find((token) => token.name === tokenOutFromParam);

      if (tokenOutDatum) {
        setTokenOut({
          name: tokenOutDatum.name,
          image: tokenOutDatum.image,
        });
      }
    }
  }, []);

  return {
    activeTab,
    setActiveTab,
    tokenIn,
    setTokenIn,
    tokenOut,
    setTokenOut,
  };
}
Example #3
Source File: useLocationStateInWrappedAssets.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
useLocationStateInWrappedAssets = () => {
  const [tokenParams, setTokenParams] = useSearchParams();
  const navigate = useNavigate();
  const location = useLocation();
  const [tokenIn, setTokenIn] = useState({
    name: 'wUSDC',
    image: wUSDC,
  });

  const [tokenOut, setTokenOut] = useState({
    name: 'USDC.e',
    image: USDCe,
  });

  const AMMExists = useMemo(() => {
    return !!config.WRAPPED_ASSETS[config.NETWORK][tokenIn.name].REF_TOKEN[tokenOut.name];
  }, [tokenIn, tokenOut]);

  const activeTab = useMemo(() => {
    if (location.pathname === '/swap') {
      return 'swap';
    }

    return 'liquidity';
  }, [location.pathname]);

  const paramKeys = useMemo(() => {
    if (activeTab === 'swap') {
      return { a: 'from', b: 'to' };
    }

    return { a: 'tokenA', b: 'tokenB' };
  }, [activeTab]);

  const setActiveTab = (elem) => {
    if (elem) {
      navigate(`/${elem}`);

      if (elem === 'liquidity' && !AMMExists) {
        setTokenOut({});
      }
    }
  };

  useEffect(() => {
    setTokenParams(
      {
        ...(tokenIn.name ? { [paramKeys.a]: tokenIn.name } : {}),
        ...(tokenParams.get(paramKeys.b) ? { [paramKeys.b]: tokenParams.get(paramKeys.b) } : {}),
      },
      { replace: true },
    );
  }, [tokenIn]);

  useEffect(() => {
    setTokenParams(
      {
        ...(tokenParams.get(paramKeys.a) ? { [paramKeys.a]: tokenParams.get(paramKeys.a) } : {}),
        ...(tokenOut.name ? { [paramKeys.b]: tokenOut.name } : {}),
      },
      { replace: true },
    );
  }, [tokenOut]);

  useEffect(() => {
    const paramKey =
      location.pathname === '/swap' ? { a: 'from', b: 'to' } : { a: 'tokenA', b: 'tokenB' };

    const tokenInFromParam = tokenParams.get(paramKey.a);
    const tokenOutFromParam = tokenParams.get(paramKey.b);

    if (tokenInFromParam) {
      const tokenInDatum = tokens.find((token) => token.name === tokenInFromParam);

      if (tokenInDatum) {
        setTokenIn({
          name: tokenInDatum.name,
          image: tokenInDatum.image,
        });
      }
    }

    if (tokenOutFromParam) {
      const tokenOutDatum = tokens.find((token) => token.name === tokenOutFromParam);

      if (tokenOutDatum) {
        setTokenOut({
          name: tokenOutDatum.name,
          image: tokenOutDatum.image,
        });
      }
    }
  }, []);

  return {
    activeTab,
    setActiveTab,
    tokenIn,
    setTokenIn,
    tokenOut,
    setTokenOut,
  };
}
Example #4
Source File: useLocationStateLiquidity.js    From plenty-interface with GNU General Public License v3.0 4 votes vote down vote up
useLocationStateInLiquidity = () => {
  const [tokenParams, setTokenParams] = useSearchParams();
  const navigate = useNavigate();
  const location = useLocation();
  const [tokenIn, setTokenIn] = useState({
    name: 'ctez',
    image: ctez,
  });
  const [tokenOut, setTokenOut] = useState({});
  useEffect(() => {
    setTokenOut({ name: 'PLENTY', image: plenty });
  }, []);
  useEffect(() => {
    if (tokenIn.name === 'tez') {
      setTokenOut({
        name: 'ctez',
        image: ctez,
      });
    } else if (tokenIn.name === 'EURL') {
      setTokenOut({
        name: 'agEUR.e',
        image: ageure,
      });
    } else if (tokenIn.name === 'agEUR.e') {
      setTokenOut({
        name: 'EURL',
        image: eurl,
      });
    }
  }, [tokenIn]);

  const AMMExists = useMemo(() => {
    if (tokenIn.name === 'tez')
      return !!config.STABLESWAP[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name];
    else return !!config.AMM[config.NETWORK][tokenIn.name].DEX_PAIRS[tokenOut.name];
  }, [tokenIn, tokenOut]);

  const activeTab = useMemo(() => {
    if (!location.pathname.includes('/liquidityPositions')) {
      return 'liquidity';
    }

    return 'liquidityPositions';
  }, [location.pathname]);

  const paramKeys = useMemo(() => {
    // if (activeTab === 'swap') {
    //   return { a: 'from', b: 'to' };
    // }

    return { a: 'tokenA', b: 'tokenB' };
  }, [activeTab]);

  const setActiveTab = (elem) => {
    if (elem) {
      navigate(`/${elem}`);

      if (elem === 'liquidity' && !AMMExists) {
        setTokenOut({});
      }
    }
  };

  useEffect(() => {
    setTokenParams(
      {
        ...(tokenIn.name ? { [paramKeys.a]: tokenIn.name } : {}),
        ...(tokenParams.get(paramKeys.b) ? { [paramKeys.b]: tokenParams.get(paramKeys.b) } : {}),
      },
      { replace: true },
    );
  }, [tokenIn]);

  useEffect(() => {
    setTokenParams(
      {
        ...(tokenParams.get(paramKeys.a) ? { [paramKeys.a]: tokenParams.get(paramKeys.a) } : {}),
        ...(tokenOut.name ? { [paramKeys.b]: tokenOut.name } : {}),
      },
      { replace: true },
    );
  }, [tokenOut]);

  useEffect(() => {
    const paramKey =
      location.pathname === '/swap' ? { a: 'from', b: 'to' } : { a: 'tokenA', b: 'tokenB' };

    const tokenInFromParam = tokenParams.get(paramKey.a);
    const tokenOutFromParam = tokenParams.get(paramKey.b);

    if (tokenInFromParam) {
      const tokenInDatum = liquidityTokens.find((token) => token.name === tokenInFromParam);

      if (tokenInDatum) {
        setTokenIn({
          name: tokenInDatum.name,
          image: tokenInDatum.image,
        });
      }
    }

    if (tokenOutFromParam) {
      const tokenOutDatum = liquidityTokens.find((token) => token.name === tokenOutFromParam);

      if (tokenOutDatum) {
        setTokenOut({
          name: tokenOutDatum.name,
          image: tokenOutDatum.image,
        });
      }
    }
  }, []);

  return {
    activeTab,
    setActiveTab,
    tokenIn,
    setTokenIn,
    tokenOut,
    setTokenOut,
  };
}