diff --git a/src/components/connection-item.tsx b/src/components/connection-item.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..34fa09b5e81372e6dd5900a576d3c6431c825d11
--- /dev/null
+++ b/src/components/connection-item.tsx
@@ -0,0 +1,13 @@
+import { ApiType } from "../services/types";
+
+interface Props {
+  value: ApiType.ConnectionsItem;
+}
+
+const ConnectionItem = (props: Props) => {
+  const { value } = props;
+
+  return <div>{value.metadata.host || value.metadata.destinationIP}</div>;
+};
+
+export default ConnectionItem;
diff --git a/src/components/list-item-link.tsx b/src/components/layout-item.tsx
similarity index 94%
rename from src/components/list-item-link.tsx
rename to src/components/layout-item.tsx
index 3e45320d18964202a534ef6976b8c2c785625166..545b36e0d1e9f633233db0c15dfe32fdb56260ae 100644
--- a/src/components/list-item-link.tsx
+++ b/src/components/layout-item.tsx
@@ -2,7 +2,7 @@ import { alpha, ListItem, ListItemButton, ListItemText } from "@mui/material";
 import { useMatch, useResolvedPath, useNavigate } from "react-router-dom";
 import type { LinkProps } from "react-router-dom";
 
-const ListItemLink = (props: LinkProps) => {
+const LayoutItem = (props: LinkProps) => {
   const { to, children } = props;
 
   const resolved = useResolvedPath(to);
@@ -41,4 +41,4 @@ const ListItemLink = (props: LinkProps) => {
   );
 };
 
-export default ListItemLink;
+export default LayoutItem;
diff --git a/src/components/log-item.tsx b/src/components/log-item.tsx
index 89e6629ad5edab175043900d916d6690c76cf32c..5a4da19779ab453d2885f70d9ac855f6dd9a043c 100644
--- a/src/components/log-item.tsx
+++ b/src/components/log-item.tsx
@@ -1,6 +1,7 @@
 import { styled, Box } from "@mui/material";
+import { ApiType } from "../services/types";
 
-const LogItem = styled(Box)(({ theme }) => ({
+const Item = styled(Box)(({ theme }) => ({
   padding: "8px 0",
   margin: "0 12px",
   lineHeight: 1.35,
@@ -8,8 +9,7 @@ const LogItem = styled(Box)(({ theme }) => ({
   "& .time": {},
   "& .type": {
     display: "inline-block",
-    width: 50,
-    margin: "0 4px",
+    padding: "0 6px",
     textAlign: "center",
     borderRadius: 2,
     textTransform: "uppercase",
@@ -18,4 +18,20 @@ const LogItem = styled(Box)(({ theme }) => ({
   "& .data": {},
 }));
 
+interface Props {
+  value: ApiType.LogItem;
+}
+
+const LogItem = (props: Props) => {
+  const { value } = props;
+
+  return (
+    <Item>
+      <span className="time">{value.time}</span>
+      <span className="type">{value.type}</span>
+      <span className="data">{value.payload}</span>
+    </Item>
+  );
+};
+
 export default LogItem;
diff --git a/src/components/profile-item.tsx b/src/components/profile-item.tsx
index 1140b629934eaa8e24979585bbde8c9c002a7e3f..cbc5e6a212ddd55eeac5cc18866d7dc31a7ee7df 100644
--- a/src/components/profile-item.tsx
+++ b/src/components/profile-item.tsx
@@ -10,7 +10,7 @@ import {
   IconButton,
 } from "@mui/material";
 import { MenuRounded } from "@mui/icons-material";
-import { ProfileItem } from "../services/command";
+import { CmdType } from "../services/types";
 import parseTraffic from "../utils/parse-traffic";
 import relativeTime from "dayjs/plugin/relativeTime";
 
@@ -29,7 +29,7 @@ const Wrapper = styled(Box)(({ theme }) => ({
 
 interface Props {
   selected: boolean;
-  itemData: ProfileItem;
+  itemData: CmdType.ProfileItem;
   onClick: () => void;
   onUpdate: () => void;
 }
diff --git a/src/components/proxy-group.tsx b/src/components/proxy-group.tsx
index bf3bb4ed2eb662abd54006fb28d0bd98510177b2..e20441c484462b6e69beeec90f5e5c3ad2d02c9b 100644
--- a/src/components/proxy-group.tsx
+++ b/src/components/proxy-group.tsx
@@ -20,11 +20,11 @@ import {
   NetworkCheckRounded,
   CheckCircleOutlineRounded,
 } from "@mui/icons-material";
-import services from "../services";
-import type { ProxyItem, ProxyGroupItem } from "../services/proxy";
+import { updateProxy } from "../services/api";
+import { ApiType } from "../services/types";
 
 interface ItemProps {
-  proxy: ProxyItem;
+  proxy: ApiType.ProxyItem;
   selected: boolean;
   onClick?: (name: string) => void;
 }
@@ -66,7 +66,7 @@ const Item = ({ proxy, selected, onClick }: ItemProps) => {
 };
 
 interface Props {
-  group: ProxyGroupItem;
+  group: ApiType.ProxyGroupItem;
 }
 
 const ProxyGroup = ({ group }: Props) => {
@@ -85,7 +85,7 @@ const ProxyGroup = ({ group }: Props) => {
     const oldValue = now;
     try {
       setNow(name);
-      await services.updateProxy(group.name, name);
+      await updateProxy(group.name, name);
     } catch {
       setNow(oldValue);
       // Todo
diff --git a/src/components/setting-clash.tsx b/src/components/setting-clash.tsx
index 72092c74ae017953bbd1c08696d70d694174686e..9b6fdcfbe6b15071657d3258c2dfd99a202ad9bc 100644
--- a/src/components/setting-clash.tsx
+++ b/src/components/setting-clash.tsx
@@ -8,8 +8,9 @@ import {
   Select,
   MenuItem,
 } from "@mui/material";
-import { ConfigType, getClashConfig, updateConfigs } from "../services/common";
-import { patchClashConfig } from "../services/command";
+import { getClashConfig, updateConfigs } from "../services/api";
+import { patchClashConfig } from "../services/cmds";
+import { ApiType } from "../services/types";
 import GuardState from "./guard-state";
 import SettingItem from "./setting-item";
 
@@ -30,11 +31,11 @@ const SettingClash = ({ onError }: Props) => {
 
   const onSwitchFormat = (_e: any, value: boolean) => value;
 
-  const onChangeData = (patch: Partial<ConfigType>) => {
+  const onChangeData = (patch: Partial<ApiType.ConfigData>) => {
     mutate("getClashConfig", { ...clashConfig, ...patch }, false);
   };
 
-  const onUpdateData = async (patch: Partial<ConfigType>) => {
+  const onUpdateData = async (patch: Partial<ApiType.ConfigData>) => {
     await updateConfigs(patch);
     await patchClashConfig(patch);
   };
diff --git a/src/components/setting-verge.tsx b/src/components/setting-verge.tsx
index ccfecdc50246d49cc46b51d5c8ff891aaf06accd..2f9fedbb260b6b2213f17cc02bd526af88ceb52a 100644
--- a/src/components/setting-verge.tsx
+++ b/src/components/setting-verge.tsx
@@ -4,8 +4,8 @@ import {
   getVergeConfig,
   patchVergeConfig,
   setSysProxy,
-  VergeConfig,
-} from "../services/command";
+} from "../services/cmds";
+import { CmdType } from "../services/types";
 import GuardState from "./guard-state";
 import SettingItem from "./setting-item";
 import PaletteSwitch from "./palette-switch";
@@ -26,7 +26,7 @@ const SettingVerge = ({ onError }: Props) => {
 
   const onSwitchFormat = (_e: any, value: boolean) => value;
 
-  const onChangeData = (patch: Partial<VergeConfig>) => {
+  const onChangeData = (patch: Partial<CmdType.VergeConfig>) => {
     mutate("getVergeConfig", { ...vergeConfig, ...patch }, false);
   };
 
diff --git a/src/components/traffic.tsx b/src/components/traffic.tsx
index 27863064e9b4862e3f3dc504c610d67b33b54c04..caee8007ab227a537d3832726b6cf40c24c71876 100644
--- a/src/components/traffic.tsx
+++ b/src/components/traffic.tsx
@@ -1,32 +1,22 @@
-import { CancelTokenSource } from "axios";
 import { useEffect, useState } from "react";
 import { Box, Typography } from "@mui/material";
 import { ArrowDownward, ArrowUpward } from "@mui/icons-material";
+import { getInfomation } from "../services/api";
+import { ApiType } from "../services/types";
 import parseTraffic from "../utils/parse-traffic";
-import services from "../services";
 
 const Traffic = () => {
   const [traffic, setTraffic] = useState({ up: 0, down: 0 });
 
   useEffect(() => {
-    let timer: any = null;
-    let source: CancelTokenSource | null = null;
+    const { server, secret } = getInfomation();
+    const ws = new WebSocket(`ws://${server}/traffic?token=${secret}`);
 
-    async function onTraffic() {
-      timer = null;
-      try {
-        source = await services.getTraffic(setTraffic);
-      } catch {
-        timer = setTimeout(onTraffic, 500);
-      }
-    }
+    ws.addEventListener("message", (event) => {
+      setTraffic(JSON.parse(event.data) as ApiType.TrafficItem);
+    });
 
-    onTraffic();
-
-    return () => {
-      if (timer) clearTimeout(timer);
-      source?.cancel();
-    };
+    return () => ws.close();
   }, []);
 
   const [up, upUnit] = parseTraffic(traffic.up);
diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx
index 72a61f20101547deac063ed7626eb66c0b840ef5..193961019d7c9500f138eb3f30696e189ca1959e 100644
--- a/src/pages/_layout.tsx
+++ b/src/pages/_layout.tsx
@@ -4,7 +4,8 @@ import { Route, Routes } from "react-router-dom";
 import { useRecoilState } from "recoil";
 import { createTheme, List, Paper, ThemeProvider } from "@mui/material";
 import { atomPaletteMode } from "../states/setting";
-import { getVergeConfig } from "../services/command";
+import { getClashInfo, getVergeConfig } from "../services/cmds";
+import { initAxios } from "../services/api";
 import LogoSvg from "../assets/image/logo.svg";
 import LogPage from "./log";
 import HomePage from "./home";
@@ -12,7 +13,7 @@ import ProfilePage from "./profile";
 import ProxyPage from "./proxy";
 import SettingPage from "./setting";
 import ConnectionsPage from "./connections";
-import ListItemLink from "../components/list-item-link";
+import LayoutItem from "../components/layout-item";
 import Traffic from "../components/traffic";
 
 const routers = [
@@ -42,6 +43,12 @@ const Layout = () => {
   const [mode, setMode] = useRecoilState(atomPaletteMode);
   const { data: vergeConfig } = useSWR("getVergeConfig", getVergeConfig);
 
+  useEffect(() => {
+    getClashInfo()
+      .then((result) => initAxios(result?.controller ?? {}))
+      .catch(() => console.error("can not initialize clash verge"));
+  }, []);
+
   useEffect(() => {
     setMode(vergeConfig?.theme_mode ?? "light");
   }, [vergeConfig?.theme_mode]);
@@ -95,9 +102,9 @@ const Layout = () => {
 
             <List sx={{ userSelect: "none" }}>
               {routers.map((router) => (
-                <ListItemLink key={router.label} to={router.link}>
+                <LayoutItem key={router.label} to={router.link}>
                   {router.label}
-                </ListItemLink>
+                </LayoutItem>
               ))}
             </List>
 
diff --git a/src/pages/connections.tsx b/src/pages/connections.tsx
index 2bd169524dc4b0e1c7ecccbb606890dac8432e3f..8a7b534e64438f86ea735620412fa6dae6ef74f7 100644
--- a/src/pages/connections.tsx
+++ b/src/pages/connections.tsx
@@ -1,21 +1,45 @@
-import { useEffect } from "react";
-import { Box, Typography } from "@mui/material";
-import services from "../services";
+import { useEffect, useState } from "react";
+import { Box, Paper, Typography } from "@mui/material";
+import { Virtuoso } from "react-virtuoso";
+import { getInfomation } from "../services/api";
+import { ApiType } from "../services/types";
+import ConnectionItem from "../components/connection-item";
 
 const ConnectionsPage = () => {
+  const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
+  const [conn, setConn] = useState<ApiType.Connections>(initConn);
+
   useEffect(() => {
-    const sourcePromise = services.getLogs(console.log);
+    const { server, secret } = getInfomation();
+    const ws = new WebSocket(`ws://${server}/connections?token=${secret}`);
+
+    ws.addEventListener("message", (event) => {
+      const data = JSON.parse(event.data) as ApiType.Connections;
+      setConn(data);
+    });
 
-    return () => {
-      sourcePromise.then((src) => src.cancel());
-    };
+    return () => ws.close();
   }, []);
 
   return (
-    <Box sx={{ width: 0.9, maxWidth: "850px", mx: "auto", mb: 2 }}>
+    <Box
+      sx={{
+        width: 0.9,
+        maxWidth: "850px",
+        height: "100%",
+        mx: "auto",
+      }}
+    >
       <Typography variant="h4" component="h1" sx={{ py: 2 }}>
         Connections
       </Typography>
+
+      <Paper sx={{ boxShadow: 2, height: "calc(100% - 100px)" }}>
+        <Virtuoso
+          data={conn.connections}
+          itemContent={(index, item) => <ConnectionItem value={item} />}
+        />
+      </Paper>
     </Box>
   );
 };
diff --git a/src/pages/log.tsx b/src/pages/log.tsx
index cf265667ac3e8d0ca04fa2bc5bfba2bb318c54cf..f10a58cb3144b64ba6251d64204d5f596ea7a0af 100644
--- a/src/pages/log.tsx
+++ b/src/pages/log.tsx
@@ -2,24 +2,26 @@ import dayjs from "dayjs";
 import { useEffect, useRef, useState } from "react";
 import { Box, Button, Paper, Typography } from "@mui/material";
 import { Virtuoso } from "react-virtuoso";
+import { ApiType } from "../services/types";
+import { getInfomation } from "../services/api";
 import LogItem from "../components/log-item";
-import services from "../services";
 
-let logCache: any[] = [];
+let logCache: ApiType.LogItem[] = [];
 
 const LogPage = () => {
-  const [logData, setLogData] = useState<any[]>(logCache);
+  const [logData, setLogData] = useState(logCache);
 
   useEffect(() => {
-    const sourcePromise = services.getLogs((t) => {
+    const info = getInfomation();
+    const ws = new WebSocket(`ws://${info.server}/logs?token=${info.secret}`);
+
+    ws.addEventListener("message", (event) => {
+      const data = JSON.parse(event.data) as ApiType.LogItem;
       const time = dayjs().format("MM-DD HH:mm:ss");
-      const item = { ...t, time };
-      setLogData((l) => (logCache = [...l, item]));
+      setLogData((l) => (logCache = [...l, { ...data, time }]));
     });
 
-    return () => {
-      sourcePromise.then((src) => src.cancel("cancel"));
-    };
+    return () => ws.close();
   }, []);
 
   return (
@@ -52,15 +54,7 @@ const LogPage = () => {
         <Virtuoso
           initialTopMostItemIndex={999}
           data={logData}
-          itemContent={(index, logItem) => {
-            return (
-              <LogItem>
-                <span className="time">{logItem.time}</span>
-                <span className="type">{logItem.type}</span>
-                <span className="data">{logItem.payload}</span>
-              </LogItem>
-            );
-          }}
+          itemContent={(index, item) => <LogItem value={item} />}
           followOutput={"smooth"}
         />
       </Paper>
diff --git a/src/pages/profile.tsx b/src/pages/profile.tsx
index 0e2317444699f8d15e1a6a132d7ee3568353451f..8cac0c48d35953bece4302a1cf53af1ddc7579be 100644
--- a/src/pages/profile.tsx
+++ b/src/pages/profile.tsx
@@ -1,13 +1,13 @@
 import { useRef, useState } from "react";
 import useSWR, { useSWRConfig } from "swr";
 import { Box, Button, Grid, TextField, Typography } from "@mui/material";
-import services from "../services";
 import {
   getProfiles,
   importProfile,
   putProfiles,
   updateProfile,
-} from "../services/command";
+} from "../services/cmds";
+import { getProxies } from "../services/api";
 import ProfileItemComp from "../components/profile-item";
 import useNotice from "../utils/use-notice";
 import noop from "../utils/noop";
@@ -44,7 +44,7 @@ const ProfilePage = () => {
     putProfiles(index)
       .then(() => {
         mutate("getProfiles", { ...profiles, current: index }, true);
-        mutate("getProxies", services.getProxies());
+        mutate("getProxies", getProxies());
       })
       .catch((err) => {
         console.error(err);
diff --git a/src/pages/proxy.tsx b/src/pages/proxy.tsx
index defaa07bd1b9380823f9730119651f8ebcbe3292..98a236fe7ae8929bfb226e04eb09ebaebb3c443d 100644
--- a/src/pages/proxy.tsx
+++ b/src/pages/proxy.tsx
@@ -1,10 +1,10 @@
 import useSWR from "swr";
 import { Box, List, Paper, Typography } from "@mui/material";
-import services from "../services";
+import { getProxies } from "../services/api";
 import ProxyGroup from "../components/proxy-group";
 
 const ProxyPage = () => {
-  const { data } = useSWR("getProxies", services.getProxies);
+  const { data } = useSWR("getProxies", getProxies);
   const { groups = [] } = data ?? {};
 
   return (
diff --git a/src/services/api.ts b/src/services/api.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f4cdb5c341b0ed0e9b223ee3c2a8fca47cba593a
--- /dev/null
+++ b/src/services/api.ts
@@ -0,0 +1,87 @@
+import axios, { AxiosInstance } from "axios";
+import { ApiType } from "./types";
+
+let axiosIns: AxiosInstance = null!;
+let server = "127.0.0.1:9090";
+let secret = "";
+
+type Callback<T> = (data: T) => void;
+
+/// initialize some infomation
+export function initAxios(info: { server?: string; secret?: string }) {
+  if (info.server) server = info.server;
+  if (info.secret) secret = info.secret;
+
+  axiosIns = axios.create({
+    baseURL: `http://${server}`,
+    headers: secret ? { Authorization: `Bearer ${secret}` } : {},
+  });
+  axiosIns.interceptors.response.use((r) => r.data);
+}
+
+/// get infomation
+export function getInfomation() {
+  return { server, secret };
+}
+
+/// Get Version
+export async function getVersion() {
+  return axiosIns.get("/version") as Promise<{
+    premium: boolean;
+    version: string;
+  }>;
+}
+
+/// Get current base configs
+export async function getClashConfig() {
+  return axiosIns.get("/configs") as Promise<ApiType.ConfigData>;
+}
+
+/// Update current configs
+export async function updateConfigs(config: Partial<ApiType.ConfigData>) {
+  return axiosIns.patch("/configs", config);
+}
+
+/// Get current rules
+export async function getRules() {
+  return axiosIns.get("/rules") as Promise<ApiType.RuleItem[]>;
+}
+
+/// Update the Proxy Choose
+export async function updateProxy(group: string, proxy: string) {
+  return axiosIns.put(`/proxies/${group}`, { name: proxy });
+}
+
+/// Get the Proxy infomation
+export async function getProxies() {
+  const response = await axiosIns.get<any, any>("/proxies");
+  const proxies = (response?.proxies ?? {}) as Record<
+    string,
+    ApiType.ProxyItem
+  >;
+
+  const global = proxies["GLOBAL"];
+  const order = global?.all;
+
+  let groups: ApiType.ProxyGroupItem[] = [];
+
+  if (order) {
+    groups = order
+      .filter((name) => proxies[name]?.all)
+      .map((name) => proxies[name])
+      .map((each) => ({
+        ...each,
+        all: each.all!.map((item) => proxies[item]),
+      }));
+  } else {
+    groups = Object.values(proxies)
+      .filter((each) => each.name !== "GLOBAL" && each.all)
+      .map((each) => ({
+        ...each,
+        all: each.all!.map((item) => proxies[item]),
+      }));
+    groups.sort((a, b) => b.name.localeCompare(a.name));
+  }
+
+  return { global, groups, proxies };
+}
diff --git a/src/services/base.ts b/src/services/base.ts
deleted file mode 100644
index 952d36ec5a086b20d82edd441fdf9143a10b6e8a..0000000000000000000000000000000000000000
--- a/src/services/base.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import axios, { AxiosInstance } from "axios";
-import { getClashInfo } from "./command";
-
-let axiosIns: AxiosInstance | null = null;
-
-export async function getAxios() {
-  if (axiosIns) return axiosIns;
-
-  let server = "127.0.0.1:9090";
-  let secret = "";
-
-  try {
-    const info = await getClashInfo();
-    const { server: server_, secret: secret_ } = info?.controller ?? {};
-    if (server_) server = server_;
-    if (secret_) secret = secret_;
-  } catch {}
-
-  axiosIns = axios.create({
-    baseURL: `http://${server}`,
-    headers: secret ? { Authorization: `Bearer ${secret}` } : {},
-  });
-  axiosIns.interceptors.response.use((r) => r.data);
-
-  return axiosIns;
-}
diff --git a/src/services/cmds.ts b/src/services/cmds.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ca2495c794236b7507c913318f3b6b0ddca2a39
--- /dev/null
+++ b/src/services/cmds.ts
@@ -0,0 +1,49 @@
+import { invoke } from "@tauri-apps/api/tauri";
+import { ApiType, CmdType } from "./types";
+
+export async function restartSidecar() {
+  return invoke<void>("restart_sidecar");
+}
+
+export async function getClashInfo() {
+  return invoke<CmdType.ClashInfo | null>("get_clash_info");
+}
+
+export async function patchClashConfig(payload: Partial<ApiType.ConfigData>) {
+  return invoke<void>("patch_clash_config", { payload });
+}
+
+export async function importProfile(url: string) {
+  return invoke<void>("import_profile", { url });
+}
+
+export async function updateProfile(index: number) {
+  return invoke<void>("update_profile", { index });
+}
+
+export async function getProfiles() {
+  return (await invoke<CmdType.ProfilesConfig>("get_profiles")) ?? {};
+}
+
+export async function setProfiles(
+  current: number,
+  profile: CmdType.ProfileItem
+) {
+  return invoke<void>("set_profiles", { current, profile });
+}
+
+export async function putProfiles(current: number) {
+  return invoke<void>("put_profiles", { current });
+}
+
+export async function setSysProxy(enable: boolean) {
+  return invoke<void>("set_sys_proxy", { enable });
+}
+
+export async function getVergeConfig() {
+  return invoke<CmdType.VergeConfig>("get_verge_config");
+}
+
+export async function patchVergeConfig(payload: CmdType.VergeConfig) {
+  return invoke<void>("patch_verge_config", { payload });
+}
diff --git a/src/services/command.ts b/src/services/command.ts
deleted file mode 100644
index d6d3c360d54cec8fa78fef080b7147763b7015c4..0000000000000000000000000000000000000000
--- a/src/services/command.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-import { invoke } from "@tauri-apps/api/tauri";
-import { ConfigType } from "./common";
-
-export async function restartSidecar() {
-  return invoke<void>("restart_sidecar");
-}
-
-export interface ClashInfo {
-  status: string;
-  controller?: { server?: string; secret?: string };
-  message?: string;
-}
-
-export async function getClashInfo() {
-  return invoke<ClashInfo | null>("get_clash_info");
-}
-
-export async function patchClashConfig(payload: Partial<ConfigType>) {
-  return invoke<void>("patch_clash_config", { payload });
-}
-
-export async function importProfile(url: string) {
-  return invoke<void>("import_profile", { url });
-}
-
-export async function updateProfile(index: number) {
-  return invoke<void>("update_profile", { index });
-}
-
-export interface ProfileItem {
-  name?: string;
-  file?: string;
-  mode?: string;
-  url?: string;
-  updated?: number;
-  selected?: { name?: string; now?: string }[];
-  extra?: {
-    upload: number;
-    download: number;
-    total: number;
-    expire: number;
-  };
-}
-
-export interface ProfilesConfig {
-  current?: number;
-  items?: ProfileItem[];
-}
-
-export async function getProfiles() {
-  return (await invoke<ProfilesConfig>("get_profiles")) ?? {};
-}
-
-export async function setProfiles(current: number, profile: ProfileItem) {
-  return invoke<void>("set_profiles", { current, profile });
-}
-
-export async function putProfiles(current: number) {
-  return invoke<void>("put_profiles", { current });
-}
-
-export async function setSysProxy(enable: boolean) {
-  return invoke<void>("set_sys_proxy", { enable });
-}
-
-export interface VergeConfig {
-  theme_mode?: "light" | "dark";
-  enable_self_startup?: boolean;
-  enable_system_proxy?: boolean;
-}
-
-export async function getVergeConfig() {
-  return invoke<VergeConfig>("get_verge_config");
-}
-
-export async function patchVergeConfig(payload: VergeConfig) {
-  return invoke<void>("patch_verge_config", { payload });
-}
diff --git a/src/services/common.ts b/src/services/common.ts
deleted file mode 100644
index 604a85eeb5ab49ecb58925c8ebf64159e52565c2..0000000000000000000000000000000000000000
--- a/src/services/common.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import axios from "axios";
-import { getAxios } from "./base";
-
-/// Get Version
-export async function getVersion() {
-  return (await getAxios()).get("/version") as Promise<{
-    premium: boolean;
-    version: string;
-  }>;
-}
-
-export interface ConfigType {
-  port: number;
-  mode: string;
-  ipv6: boolean;
-  "socket-port": number;
-  "allow-lan": boolean;
-  "log-level": string;
-  "mixed-port": number;
-  "redir-port": number;
-  "socks-port": number;
-  "tproxy-port": number;
-}
-
-/// Get current base configs
-export async function getClashConfig() {
-  return (await getAxios()).get("/configs") as Promise<ConfigType>;
-}
-
-/// Update current configs
-export async function updateConfigs(config: Partial<ConfigType>) {
-  return (await getAxios()).patch("/configs", config);
-}
-
-interface RuleItem {
-  type: string;
-  payload: string;
-  proxy: string;
-}
-
-/// Get current rules
-export async function getRules() {
-  return (await getAxios()).get("/rules") as Promise<RuleItem[]>;
-}
-
-/// Get logs stream
-export async function getLogs(callback: (t: any) => void) {
-  const source = axios.CancelToken.source();
-
-  (await getAxios()).get("/logs", {
-    cancelToken: source.token,
-    onDownloadProgress: (progressEvent) => {
-      const data = progressEvent.currentTarget.response || "";
-      const lastData = data.slice(data.trim().lastIndexOf("\n") + 1);
-      callback(JSON.parse(lastData));
-    },
-  });
-
-  return source;
-}
diff --git a/src/services/index.ts b/src/services/index.ts
deleted file mode 100644
index 434a9d35911b0c18e79bc03cb094b96b325d7324..0000000000000000000000000000000000000000
--- a/src/services/index.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import * as common from "./common";
-import * as proxy from "./proxy";
-import * as traffic from "./traffic";
-
-export default {
-  ...common,
-  ...proxy,
-  ...traffic,
-};
diff --git a/src/services/proxy.ts b/src/services/proxy.ts
deleted file mode 100644
index 1f29ac9c2e07dfdb3552727e89979c0d5f95404b..0000000000000000000000000000000000000000
--- a/src/services/proxy.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { getAxios } from "./base";
-
-export interface ProxyItem {
-  name: string;
-  type: string;
-  udp: boolean;
-  history: {
-    time: string;
-    delay: number;
-  }[];
-  all?: string[];
-  now?: string;
-}
-
-export type ProxyGroupItem = Omit<ProxyItem, "all"> & {
-  all: ProxyItem[];
-};
-
-/// Get the Proxy infomation
-export async function getProxies() {
-  const axiosIns = await getAxios();
-  const response = await axiosIns.get<any, any>("/proxies");
-  const proxies = (response?.proxies ?? {}) as Record<string, ProxyItem>;
-
-  const global = proxies["GLOBAL"];
-  const order = global?.all;
-
-  let groups: ProxyGroupItem[] = [];
-
-  if (order) {
-    groups = order
-      .filter((name) => proxies[name]?.all)
-      .map((name) => proxies[name])
-      .map((each) => ({
-        ...each,
-        all: each.all!.map((item) => proxies[item]),
-      }));
-  } else {
-    groups = Object.values(proxies)
-      .filter((each) => each.name !== "GLOBAL" && each.all)
-      .map((each) => ({
-        ...each,
-        all: each.all!.map((item) => proxies[item]),
-      }));
-    groups.sort((a, b) => b.name.localeCompare(a.name));
-  }
-
-  return { global, groups, proxies };
-}
-
-/// Update the Proxy Choose
-export async function updateProxy(group: string, proxy: string) {
-  return (await getAxios()).put(`/proxies/${group}`, { name: proxy });
-}
diff --git a/src/services/traffic.ts b/src/services/traffic.ts
deleted file mode 100644
index a4c760feb55897e174d05ec0ce2a6d6bec0fa2ce..0000000000000000000000000000000000000000
--- a/src/services/traffic.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import axios from "axios";
-import { getAxios } from "./base";
-
-export interface TrafficData {
-  up: number;
-  down: number;
-}
-
-/// Get the traffic stream
-export async function getTraffic(callback: (data: TrafficData) => void) {
-  const source = axios.CancelToken.source();
-
-  (await getAxios()).get("/traffic", {
-    cancelToken: source.token,
-    onDownloadProgress: (progressEvent) => {
-      const data = progressEvent.currentTarget.response || "";
-      const lastData = data.slice(data.trim().lastIndexOf("\n") + 1);
-
-      if (!lastData) callback({ up: 0, down: 0 });
-      try {
-        callback(JSON.parse(lastData) as TrafficData);
-      } catch {
-        callback({ up: 0, down: 0 });
-      }
-    },
-  });
-
-  return source;
-}
diff --git a/src/services/types.ts b/src/services/types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3544c42e56d5a6157702dc1adf3fb9b209f1137c
--- /dev/null
+++ b/src/services/types.ts
@@ -0,0 +1,115 @@
+/**
+ * Some interface for clash api
+ */
+export namespace ApiType {
+  export interface ConfigData {
+    port: number;
+    mode: string;
+    ipv6: boolean;
+    "socket-port": number;
+    "allow-lan": boolean;
+    "log-level": string;
+    "mixed-port": number;
+    "redir-port": number;
+    "socks-port": number;
+    "tproxy-port": number;
+  }
+
+  export interface RuleItem {
+    type: string;
+    payload: string;
+    proxy: string;
+  }
+
+  export interface ProxyItem {
+    name: string;
+    type: string;
+    udp: boolean;
+    history: {
+      time: string;
+      delay: number;
+    }[];
+    all?: string[];
+    now?: string;
+  }
+
+  export type ProxyGroupItem = Omit<ProxyItem, "all"> & {
+    all: ProxyItem[];
+  };
+
+  export interface TrafficItem {
+    up: number;
+    down: number;
+  }
+
+  export interface LogItem {
+    type: string;
+    time?: string;
+    payload: string;
+  }
+
+  export interface ConnectionsItem {
+    id: string;
+    metadata: {
+      network: string;
+      type: string;
+      host: string;
+      sourceIP: string;
+      sourcePort: string;
+      destinationPort: string;
+      destinationIP?: string;
+    };
+    upload: number;
+    download: number;
+    start: string;
+    chains: string[];
+    rule: string;
+    rulePayload: string;
+  }
+
+  export interface Connections {
+    downloadTotal: number;
+    uploadTotal: number;
+    connections: ConnectionsItem[];
+  }
+}
+
+/**
+ * Some interface for command
+ */
+export namespace CmdType {
+  export interface ClashInfo {
+    status: string;
+    controller?: { server?: string; secret?: string };
+    message?: string;
+  }
+
+  export interface ProfileItem {
+    name?: string;
+    file?: string;
+    mode?: string;
+    url?: string;
+    updated?: number;
+    selected?: {
+      name?: string;
+      now?: string;
+    }[];
+    extra?: {
+      upload: number;
+      download: number;
+      total: number;
+      expire: number;
+    };
+  }
+
+  export interface ProfilesConfig {
+    current?: number;
+    items?: ProfileItem[];
+  }
+
+  export interface VergeConfig {
+    theme_mode?: "light" | "dark";
+    enable_self_startup?: boolean;
+    enable_system_proxy?: boolean;
+  }
+}