million 1 yıl önce
ebeveyn
işleme
8d870a88f5

+ 13 - 0
src/router/index.ts

@@ -1,5 +1,8 @@
 import { createRouter, createWebHistory } from 'vue-router'
 import HomeView from '../views/HomeView.vue'
+import ZksyncView from '../views/ZksyncView.vue'
+import LayerZero from '../views/LayerZeroView.vue'
+
 
 const router = createRouter({
   history: createWebHistory(import.meta.env.BASE_URL),
@@ -9,6 +12,16 @@ const router = createRouter({
       name: 'home',
       component: HomeView
     },
+    {
+      path: '/zksync',
+      name: 'zksync',
+      component: ZksyncView
+    },
+    {
+      path: '/layerZero',
+      name: 'layerZero',
+      component: LayerZero
+    }
   ]
 })
 

+ 88 - 0
src/utils/getLayerData.js

@@ -0,0 +1,88 @@
+import axios from "axios";
+
+const netMap = {
+    "bsc": "https://api.bscscan.com",
+    "ftm": "https://api.ftmscan.com",
+    "metis": "https://andromeda-explorer.metis.io",
+    "avax": "https://api.snowtrace.io",
+    "matic": "https://api.polygonscan.com",
+    "arb": "https://api.arbiscan.io",
+    "op": "https://api-optimistic.etherscan.io",
+    "eth": "https://api.etherscan.io"
+}
+const keyMap = {
+    "bsc": ["IHA6XUNGC9A8CS1EVB4ZKMMNCEVWQYWGNF", "35GX1RBQBNKDSS2QFF8YZ9IJ4MUPD8FBV4",
+        "KD21NU93H2696XZGUE6IIZX291V2291WBZ"],
+    "ftm": ["7NS7WM87WNYTDWXFRUP1QFVEGEMEWWTT1R", "JUEKUR5XBG5Z4WQUV71IZHJCPGVWADGHY3",
+        "YCTIQFTS8AXJQVE84CYY2FSGU9JYHWTEMN"],
+    "metis": [null],
+    "avax": ["XZVMR1A53KHXIEZV2X5QYZ2GSYFDDHUGVS", "PX4ZC7BFCMF51E7DC7JKDWERHYCW8JNPM7",
+        "B4XCRBZYZX26NGZG1XJB7UIDGDWF8TYSHT"],
+    "matic": ["5N7B38PZTENUK44XDF3WUPFFN68ICZ87Y3", "SIKU51V7YGAYUZF8HJ7R5FE6WHBP4Z6VEI",
+        "SMIPK99XJR9IXRSSCDHWJB8CT4YKTKJC4E"],
+    "arb": ["FTAT7G2F45P8VNVQG66SGF7T4TS6R2QFGY", "MXKDX8ZX8H5P34WFXFZF1YEPA6X6DDIV5R",
+        "WBCVFF7GVC4XJZFMS3EZJVVPMAH14IT7SU"],
+    "op": ["C8JSVBMBI2NBBYWUJ99ZR2QCQ8GB33NFGB"],
+    "eth": ["FPFT5EGK6F4JS97IA4E8SI24UN559W53VI", "XHSCQN5JZHT4WY1JCATJTN4IDGX2PU6WHH",
+        "ADX2IDIUKD57WAM1GN6YA9E9Y9R3W5CXMC"]
+}
+let txMap = {}
+
+async function getLayerData(address, apiKeyData) {
+    const txMapPromises = Object.keys(netMap).map(async (net) => {
+        try {
+            const u = netMap[net];
+            let k;
+            if (apiKeyData && net in apiKeyData && apiKeyData[net]) {
+                k = apiKeyData[net];
+            } else {
+                const keys = keyMap[net];
+                const index = Math.floor(Math.random() * keys.length);
+                k = keys[index];
+            }
+            let tx = 0;
+            address = address.toLowerCase();
+            let url;
+            if (k === null) {
+                url = `${u}/api?module=account&action=txlist&address=${address}&startblock=0&endblock=99999999&page=1&offset=10000&sort=asc`;
+            } else {
+                url = `${u}/api?module=account&action=txlist&address=${address}&startblock=0&endblock=99999999&page=1&offset=10000&sort=asc&apikey=${k}`;
+            }
+            const res = await axios.get(url);
+            let timeArr = []
+            for (let i = 0; i < res.data.result.length; i++) {
+                const methodId = res.data.result[i].input.slice(0, 10);
+                if (res.data.result[i].from === address && res.data.result[i]['txreceipt_status'] === "1") {
+                    const methodIds =
+                        ["0x9fbf10fc", "0x1114cd2a", "0xc858f5f9", "0x76a9099a", "0x2e15238c", "0xae30f6ee",
+                            "0xc45dec27", "0x2cdf0b95", "0x879762e2", "0x656f3d64", "0x51905636", "0xad660825",
+                            "0xfe359a0d", "0xca23bb4c", "0x00000005"];
+                    if (methodIds.includes(methodId)) {
+                        tx += 1;
+                        timeArr.push(res.data.result[i])
+                    }
+                }
+            }
+            return {net, tx, timeArr};
+        } catch (e) {
+            console.log(e.message);
+            return {net, tx: "0"};
+        }
+    });
+
+    const txMapResults = await Promise.all(txMapPromises);
+    let totalTx = 0;
+    let arr = []
+    txMapResults.forEach(({net, tx , timeArr}) => {
+        if (tx !== "0") {
+            totalTx += tx;
+            arr.push(...timeArr)
+        }
+        txMap[net] = tx;
+    });
+    txMap.arr = arr
+    txMap["total"] = totalTx;
+    return txMap;
+}
+
+export default getLayerData

+ 1 - 930
src/views/HomeView.vue

@@ -1,940 +1,11 @@
 <script setup lang="ts">
-//@ts-ignore
-import MetaMaskSDK from '../utils/metamask-sdk.js'
-//@ts-ignore
-import getZksEra from '../utils/getZksEra.js'
-//@ts-ignore
-import getZksLite from '../utils/getZksLite.js'
-//@ts-ignore
-import getZkSyncBridge from '../utils/getZkSyncBridge.js'
-import * as echarts from 'echarts';
-import {onMounted, ref} from 'vue';
-import balancerBg from '../project/balancer/balancerBg.png'
-import balancerAv from '../project/balancer/balancerAv.png'
-import argentBg from '../project/argent/argentBg.png'
-import argentAv from '../project/argent/argentAv.png'
-import ontoBg from '../project/onto/ontoBg.png'
-import ontoAv from '../project/onto/ontoAv.png'
-import zerionBg from '../project/zerion/zerionBg.png'
-import zerionAv from '../project/zerion/zerionAv.png'
-import zksEraBridgeAv from '../project/zksEraBridge/zksEraBridgeAv.png'
-import zksEraBridgeBg from '../project/zksEraBridge/zksEraBridgeBg.png'
-import zksLiteBridgeBg from '../project/zksLiteBridge/zksLiteBridgeBg.png'
-import zksLiteBridgeAv from '../project/zksLiteBridge/zksLiteBridgeAv.png'
-import orbiterAv from '../project/orbiter/orbiterAv.png'
-import orbiterBg from '../project/orbiter/orbiterBg.png'
-import muteAv from '../project/mute/muteAv.png'
-import muteBg from '../project/mute/muteBg.png'
-import syncswapBg from '../project/syncswap/syncswapBg.png'
-import syncswapAv from '../project/syncswap/syncswapAv.png'
-import getcoinBg from '../project/getcoin/getcoinBg.png'
-import getcoinAv from '../project/getcoin/getcoinAv.png'
 
-
-
-
-type EChartsOption = echarts.EChartsOption;
-
-onMounted(() => {
-  checkWalletAddress()
-  listeningDisconnect()
-})
-
-
-type dataArrType = {
-  name: string,
-  type: string[],
-  BG: string,
-  avatar: string,
-  url:string
-}[]
-let dataArr: dataArrType = [
-  {
-    name: 'zks-era bridge',
-    type: ['OFFICAL','BRIDGE'],
-    BG: zksEraBridgeBg,
-    avatar: zksEraBridgeAv,
-    url:'https://bridge.zksync.io/'
-  },
-  {
-    name: 'zks-lite bridge',
-    type: ['OFFICAL','BRIDGE'],
-    BG: zksLiteBridgeBg,
-    avatar: zksLiteBridgeAv,
-    url:'https://lite.zksync.io/transaction/deposit'
-  },
-  {
-    name: 'Orbiter',
-    type: ['ERA', 'SWAP'],
-    BG: orbiterBg,
-    avatar: orbiterAv,
-    url:'https://www.orbiter.finance/'
-  },
-  {
-    name: 'Mute',
-    type: ['ERA', 'DEFI', 'SWAP'],
-    BG: muteBg,
-    avatar: muteAv,
-    url:'https://app.mute.io/swap'
-  },
-  {
-    name: 'Syncswap',
-    type: ['ERA', 'SWAP'],
-    BG: syncswapBg,
-    avatar: syncswapAv,
-    url:'https://syncswap.xyz/'
-  },
-  {
-    name: 'Gitcoin',
-    type: ['DEFI', 'SWAP'],
-    BG: getcoinBg,
-    avatar: getcoinAv,
-    url:'https://bounties.gitcoin.co/'
-  },
-]
-
-let MM = ref()//MetaMaskSDK
-let address = ref('')//钱包地址
-let chainId = '0x144'
-const MMSDK = new MetaMaskSDK()
-MM.value = MMSDK.getProvider()
-
-//监听连接断开(通过监听账号的变化判断是否断开连接)
-const listeningDisconnect = () => {
-  MM.value.on('accountsChanged', (accounts: string[]) => {
-    if (accounts.length >= 1) {
-      address.value = accounts[0]
-      connectWallet()
-    } else {
-      address.value = ''
-    }
-  })
-}
-//查询钱包地址
-const checkWalletAddress = async () => {
-  let accounts: string[] = await MM.value.request({method: 'eth_accounts'});//不弹窗
-  address.value = accounts[0]
-  getMainTx()
-  getLiteTx()
-  getMoreInfo()
-  await addChain()
-  await switchEthereumChain()
-}
-//添加链
-const addChain = () => {
-  MM.value.request({
-    method: 'wallet_addEthereumChain',
-    params: [{
-      chainId: chainId,
-      chainName: 'zkSync Era Mainnet',
-      rpcUrls: ['https://mainnet.era.zksync.io'],
-      blockExplorerUrls: ['https://explorer.zksync.io'],
-      nativeCurrency: {
-        name: 'ETH',
-        symbol: 'ETH',
-        decimals: 18,
-      },
-    }]
-  })
-}
-//切换链
-const switchEthereumChain = () => {
-  MM.value.request({
-    method: 'wallet_switchEthereumChain',
-    params: [{chainId: chainId}],
-  }).then(() => {
-
-  }).catch(() => {
-
-  });
-}
-//连接钱包按钮
-const connectWallet = async () => {
-  let accounts: string[] = await MM.value.request({method: 'eth_requestAccounts'});
-  address.value = accounts[0]
-  getMainTx()
-  getLiteTx()
-  getMoreInfo()
-  await addChain()
-  await switchEthereumChain()
-}
-//获取主网交易次数
-let mainTx = ref(0)
-const getMainTx = () => {
-  getZksEra(address.value).then(({tx2}:{tx2:number}) => {
-    mainTx.value = tx2
-  })
-}
-//获取lite网交易次数
-let liteTx = ref(0)
-const getLiteTx = () => {
-  getZksLite(address.value).then(({tx1}:{tx1:number}) => {
-    liteTx.value = tx1
-  })
-}
-//获取更多信息
-let amount = ref(0)
-let contract = ref(0)
-let tradingTimeArr = ref()
-let l1Tol2Tx = ref(0)
-let l2Tol1Tx = ref(0)
-const getMoreInfo = () => {
-  getZkSyncBridge(address.value).then((
-      {
-          totalExchangeAmount,
-          contractActivity,
-          overTimeArr,
-          l1Tol2Times,
-          l2Tol1Times
-      }:{
-        totalExchangeAmount:number
-        contractActivity:number
-        overTimeArr:any
-        l1Tol2Times:number
-        l2Tol1Times:number
-      }) => {
-    amount.value = totalExchangeAmount
-    contract.value = contractActivity
-    tradingTimeArr.value = overTimeArr
-    l1Tol2Tx.value = l1Tol2Times
-    l2Tol1Tx.value = l2Tol1Times
-    processTime()
-  })
-}
-//处理时间数据
-const monthArr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
-let showMonthNumberArr = ref([0,0,0,0,0,0,0,0,0,0,0,0])
-let showMonthArr = ref()
-const processTime = () => {
-  let nowDate = new Date().toString()
-  let nowDateArr = nowDate.split(' ')
-  let nowMonth = nowDateArr[1]
-  showMonthArr.value = []
-  showMonthArr.value.push(nowMonth)
-  let nowMonthIndex = monthArr.indexOf(nowMonth)
-  const forLoop = () => {
-    for (let i = 11; i !== nowMonthIndex ; i--) {
-      showMonthArr.value.unshift(monthArr[i])
-    }
-  }
-  for (let i = nowMonthIndex; i !== 0 ; i--) {
-    showMonthArr.value.unshift(monthArr[i-1])
-    if (i === 1) {
-      forLoop()
-    }
-  }
-  if (tradingTimeArr.value){
-    tradingTimeArr.value.forEach((item:any) => {
-      if(item.balanceChanges[0].from && item.balanceChanges[0].from.toLowerCase() === address.value.toLowerCase()){
-        let receivedAt = new Date(Date.parse(item.receivedAt)).toString();
-        let strArr = receivedAt.split(' ')
-        let month = strArr[1]
-        let index = showMonthArr.value.indexOf(month)
-        showMonthNumberArr.value[index]++
-      }
-    })
-  }
-
-  initEcharts()
-
-}
-
-//初始化echarts
-const initEcharts = () => {
-  let chartDom = document.getElementById('echartsBox')!
-  let myChart = echarts.init(chartDom);
-  let option: EChartsOption;
-
-  option = {
-    tooltip: {
-      trigger: 'axis',
-      axisPointer: {
-        type: 'shadow'
-      }
-    },
-    xAxis: {
-      type: 'category',
-      axisTick: {
-        alignWithLabel: true
-      },
-      data: showMonthArr.value
-    },
-    yAxis: {
-      type: 'value',
-    },
-    series: [
-      {
-        color: '#000000',
-        data: showMonthNumberArr.value,
-        type: 'bar'
-      }
-    ]
-  };
-
-  option && myChart.setOption(option);
-}
-
-//跳转网页
-const toLink = (url:string) => {
-  window.open(url)
-}
-
-const toEmail = (email:string) => {
-  const emailAddress = email; // 替换为你想发送邮件的收件人地址
-  const subject = 'Hello'; // 替换为你想在邮件中设置的主题
-  const body = 'This is the email body.'; // 替换为你想在邮件中设置的内容
-
-  const mailtoUrl = `mailto:${emailAddress}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
-
-  window.open(mailtoUrl);
-}
-
-let sun = ref(true)
-const sunAndMoon = () => {
-  if (sun.value){
-    document.documentElement.style.setProperty('--color-background','#181818')
-    document.documentElement.style.setProperty('--color-text','#f2f2f2')
-    document.documentElement.style.setProperty('--vt-c-border','#555555')
-  }else {
-    document.documentElement.style.setProperty('--color-background','#f2f2f2')
-    document.documentElement.style.setProperty('--color-text','#181818')
-    document.documentElement.style.setProperty('--vt-c-border','#f7f7f7')
-
-  }
-  sun.value = !sun.value
-
-}
 </script>
 
 <template>
-  <main class="main">
-    <div class="mainBG">
-      <img src="../assets/BG.png" alt="BG">
-    </div>
-    <div class="topBar">
-      <div class="left">
-        <img v-show="!sun" src="../assets/bitflower-white.svg" alt="bitflower">
-        <img v-show="sun" src="../assets/bitflower.svg" alt="logo">
-
-        <div class="navOne">
-          Home
-<!--          <div class="line"/>-->
-        </div>
-        <div class="nav">
-          NFT
-<!--          <div class="line"/>-->
-        </div>
-        <div class="nav">
-          Query
-          <div class="line"/>
-        </div>
-      </div>
-<!--      <div class="mid">-->
-<!--        Blossom your Web3 Trip ✈-->
-<!--      </div>-->
-      <div class="right">
-        <img v-show="!sun" @click="sunAndMoon" src="../assets/sun-fill.svg" alt="sun-fill">
-        <img v-show="sun" @click="sunAndMoon" src="../assets/moon-clear-fill.svg" alt="moon-clear-fill">
-        <div class="button" v-show="!address" @click="connectWallet">
-          <img src="../assets/git-commit-line.svg" alt="commit">
-          Connect Wallet
-        </div>
-        <div class="connect" v-if="address">
-          <img src="../assets/git-commit-line-black.svg" alt="commit">
-          {{ address.slice(0, 8) }}...{{ address.slice(-4) }}
-        </div>
-      </div>
-    </div>
-    <div class="chainBox">
-      <div class="item">
-        zkSync
-        <div class="line"></div>
-      </div>
-      <div class="item" style="cursor: pointer" @click="toLink('https://layer0.biflower.cc')">
-        Layer Zero
-      </div>
-      <div class="item">
-        StarkNet
-      </div>
-    </div>
-    <div class="dataColumn">
-      <div class="item">
-        <div class="top">
-          <div class="img">
-            <img v-show="!sun" src="../assets/group1-white.svg" alt="group1">
-            <img v-show="sun" src="../assets/group1.svg" alt="group1">
-          </div>
-          <div class="title">
-            Protocols lnteraction
-            <el-popover
-                placement="bottom"
-                :width="230"
-                trigger="hover"
-                effect="dark"
-            >
-              <template #reference>
-                <img src="../assets/info.svg" alt="info">
-              </template>
-              <div class="popoverText">
-                Number of protocolsinteracted
-              </div>
-              <div class="popoverText">
-                with out of allavailable protocols
-              </div>
-            </el-popover>
-          </div>
-        </div>
-        <div class="number">
-          {{ contract }}
-        </div>
-      </div>
-      <div class="line" style="left:270px">
-
-      </div>
-      <div class="item">
-        <div class="top">
-          <div class="img">
-            <img v-show="!sun" class="img" src="../assets/group3-white.svg" alt="group2">
-            <img v-show="sun" class="img" src="../assets/group3.svg" alt="group2">
-          </div>
-          <div class="title">
-            Total Transactions
-            <el-popover
-                placement="bottom"
-                :width="250"
-                trigger="hover"
-                effect="dark"
-            >
-              <template #reference>
-                <img src="../assets/info.svg" alt="info">
-              </template>
-              <div class="popoverText">
-                Total zkSync lite
-              </div>
-              <div class="popoverText">
-                transactions issuedfrom the account
-              </div>
-            </el-popover>
-          </div>
-        </div>
-        <div class="number">
-          {{ liteTx }}
-          <img @click="toLink('https://zkscan.io/')" style="cursor: pointer" src="../assets/arrow-right-up-line.svg" alt="arrow">
-        </div>
-      </div>
-      <div class="item">
-        <div class="top">
-          <div class="img">
-            <img v-show="!sun" class="img" src="../assets/group2-white.svg" alt="group2">
-            <img v-show="sun" class="img" src="../assets/group2.svg" alt="group2">
-          </div>
-          <div class="title">
-            Total Transactions
-            <el-popover
-                placement="bottom"
-                :width="250"
-                trigger="hover"
-                effect="dark"
-            >
-              <template #reference>
-                <img src="../assets/info.svg" alt="info">
-              </template>
-              <div class="popoverText">
-                Total zkSync era
-              </div>
-              <div class="popoverText">
-                transactions issuedfrom the account
-              </div>
-            </el-popover>
-          </div>
-        </div>
-        <div class="number">
-          {{ mainTx }}
-          <img @click="toLink('https://explorer.zksync.io/')" style="cursor: pointer" src="../assets/arrow-right-up-line.svg" alt="arrow">
-        </div>
-      </div>
-      <div class="item" style="height: 94px">
-        <div class="top">
-          <div class="img">
-            <img v-show="!sun" class="img" src="../assets/official-bridge-white.svg" alt="group2">
-            <img v-show="sun" class="img" src="../assets/official-bridge-black.svg" alt="group2">
-          </div>
-          <div style="display: flex;gap:40px">
-            <div style="display: flex;flex-direction: column;gap:20px">
-              <img v-show="!sun" src="../assets/L1-To-L2-white.svg" alt="To">
-              <img v-show="sun" src="../assets/L1-To-L2.svg" alt="To">
-              <div class="number">
-                {{ l1Tol2Tx }}
-              </div>
-            </div>
-            <div style="display: flex;flex-direction: column;gap:20px">
-              <img v-show="!sun" src="../assets/L2-To-L1-white.svg" alt="To">
-              <img v-show="sun" src="../assets/L2-To-L1.svg" alt="To">
-              <div class="number">
-                {{ l2Tol1Tx }}
-              </div>
-            </div>
-          </div>
-        </div>
-
-      </div>
-      <div class="line" style="right:370px">
 
-      </div>
-      <div class="item">
-        <div class="top">
-          <div class="img">
-            <img class="img" src="../assets/group4.svg" alt="group2">
-          </div>
-          <div class="title">
-            Total amount spent
-          </div>
-        </div>
-        <div class="number">
-          {{ amount }} USDT
-        </div>
-      </div>
-    </div>
-    <div class="primary">
-      <div class="left">
-        <div class="echarts">
-          <div class="title">
-            Transactions Over Time
-            <el-popover
-                placement="right"
-                :width="240"
-                trigger="hover"
-                effect="dark"
-            >
-              <template #reference>
-                <img src="../assets/info.svg" alt="info">
-              </template>
-              <div class="popoverText">
-                Number of transactions permonth
-              </div>
-            </el-popover>
-          </div>
-          <div class="echartsBox" id="echartsBox">
-
-          </div>
-        </div>
-        <div class="disclaimer">
-          <img v-show="!sun" src="../assets/disclaimer-white.svg" alt="disclaimer">
-          <img v-show="sun" src="../assets/disclaimer.svg" alt="disclaimer">
-          <div class="description">
-            The list of dApps is for informational purposes only. It is not a testimony of the security or reliability
-            of any dApp. Furthermore, most dApps are currently in alpha stage and their code is not audited. You are
-            encouraged to do your own research (DYOR) before interacting with, or investing in any dApps. This should
-            not be considered financial or investment advice.
-          </div>
-          <div class="contact">
-            <div class="item" @click="toEmail('bitflower.web3@gmail.com')">
-              <img src="../assets/mail-open-line.svg" alt="mail">
-              E-mail
-            </div>
-            <div class="line"/>
-            <div class="item" @click="toLink('https://t.me/bitflowersupport')">
-              <img src="../assets/telegram-line.svg" alt="telegram">
-              Telegram
-            </div>
-          </div>
-        </div>
-      </div>
-      <div class="right">
-        <div class="item" @click="toLink(item.url)" v-for="item in dataArr">
-          <div class="BG">
-            <img class="BG" :src="item.BG" alt="BG">
-          </div>
-          <div class="infoBox">
-            <div class="avatar">
-              <img class="avatar" :src="item.avatar" alt="avatar">
-            </div>
-            <div class="nameAndType">
-              <div class="name">
-                {{ item.name }}
-              </div>
-              <div class="typeBox">
-                <div class="type" v-for="item1 in item.type">
-                  {{ item1 }}
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </main>
 </template>
 
-<style lang="scss">
-.main {
-  width: 1440px;
-  height: 100%;
-  margin: auto;
-  border: 1px solid var(--vt-c-border);
-  border-top: none;
-  border-bottom: none;
-  padding: 30px 60px;
-  .mainBG{
-    position: absolute;
-    top: 0;
-    z-index: -1;
-  }
-  .topBar {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    padding: 0 60px 25px;
-    margin: 0 -60px;
-    border-bottom: 1px solid var(--vt-c-border);
-    .left{
-      display: flex;
-      align-items: center;
-      .nav{
-        font-family: HONOR Sans CN;
-        font-size: 21px;
-        font-style: normal;
-        font-weight: 700;
-        line-height: normal;
-        padding: 0 60px;
-        height: 100px;
-        display: flex;
-        align-items: center;
-        margin-bottom: -25px;
-        margin-top: -30px;
-        border-right: 1px solid var(--vt-c-border);
-        position: relative;
-        .line{
-          position: absolute;
-          width: 100%;
-          height: 10px;
-          background: var(--color-text);
-          left: 0;
-          bottom: 0;
-        }
-      }
-      .navOne{
-        font-family: HONOR Sans CN;
-        font-size: 21px;
-        font-style: normal;
-        font-weight: 700;
-        line-height: normal;
-        padding: 0 60px;
-        height: 100px;
-        display: flex;
-        align-items: center;
-        margin-bottom: -25px;
-        margin-top: -30px;
-        border-right: 1px solid var(--vt-c-border);
-        margin-left: 57px;
-        border-left: 1px solid var(--vt-c-border);
-        position: relative;
-        .line{
-          position: absolute;
-          width: 100%;
-          height: 10px;
-          background: var(--color-text);
-          left: 0;
-          bottom: 0;
-        }
-      }
-    }
-    .mid{
-      font-weight: 400;
-      font-size: 15px;
-      line-height: 21px;
-      font-family: 'Chillax';
-      text-transform: uppercase;
-    }
-    .right {
-      display: flex;
-      align-items: center;
-      gap:40px;
-      cursor: pointer;
-
-      .button {
-        width: fit-content;
-        height: 44px;
-        display: flex;
-        align-items: center;
-        gap: 6px;
-        background: #010101;
-        padding: 0 24px;
-        font-weight: 500;
-        font-size: 15px;
-        line-height: 20px;
-        color: #FFFFFF;
-        cursor: pointer;
-      }
-
-      .connect {
-        width: fit-content;
-        height: 44px;
-        display: flex;
-        align-items: center;
-        gap: 6px;
-        background: #FFFFFF;
-        border: 1px solid #010101;
-        border-radius: 30px;
-        padding: 0 24px;
-        font-weight: 500;
-        font-size: 15px;
-        line-height: 20px;
-        color: #010101;
-      }
-    }
-  }
-  .chainBox{
-    width: 100%;
-    display: flex;
-    align-items: center;
-    margin: 0 -60px;
-    .item{
-      padding: 24px 65px;
-      border-right: 1px solid var(--vt-c-border);
-      font-family: HONOR Sans CN;
-      font-size: 15px;
-      font-style: normal;
-      font-weight: 700;
-      line-height: normal;
-      position: relative;
-      .line{
-        position: absolute;
-        width: 60px;
-        height: 4px;
-        background: var(--color-text);
-        left: 0;
-        right: 0;
-        margin: auto;
-        bottom: 0;
-      }
-    }
-  }
-  .dataColumn {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    padding: 60px;
-    border-bottom: 1px solid var(--vt-c-border);
-    border-top: 1px solid var(--vt-c-border);
-    margin: 0 -60px;
-    position: relative;
-
-    .item {
-      width: 330px;
-      display: flex;
-      flex-direction: column;
-      gap: 20px;
-
-      .top {
-        display: flex;
-        flex-direction: column;
-        gap: 6px;
-
-        .img {
-          height: 16px;
-        }
-
-        .title {
-          display: flex;
-          align-items: center;
-          gap: 8px;
-          font-weight: 400;
-          font-size: 14px;
-          line-height: 18px;
-          //color: #010101;
-          font-family: 'HONOR Sans CN';
-          .popoverText{
-            font-weight: 400;
-            font-size: 12px;
-            line-height: 24px;
-          }
-        }
-      }
-
-      .number {
-        display: flex;
-        align-items: center;
-        gap: 8px;
-        font-weight: 700;
-        font-size: 26px;
-        line-height: 34px;
-        //color: #010101;
-      }
-    }
-
-    .line {
-      width: 1px;
-      height: 100%;
-      border-right: 1px solid var(--vt-c-border);
-      position: absolute;
-    }
-  }
-
-  .primary {
-    display: flex;
-    gap: 60px;
-    margin-top: 60px;
-
-    .left {
-      display: flex;
-      flex-direction: column;
-
-      .echarts {
-        .title {
-          display: flex;
-          align-items: center;
-          gap: 8px;
-          font-weight: 700;
-          font-size: 14px;
-          line-height: 18px;
-          //color: #010101;
-        }
-
-        .echartsBox {
-          height: 360px;
-          width: 560px;
-        }
-      }
-
-      .disclaimer {
-        width: 558px;
-        height: 246px;
-        border: 1px solid #010101;
-        padding: 24px;
-
-        .description {
-          margin-top: 8px;
-          margin-bottom: 28px;
-          font-weight: 400;
-          font-size: 12px;
-          line-height: 24px;
-          color: #808080;
-        }
-
-        .contact {
-          width: fit-content;
-          height: 44px;
-          display: flex;
-          align-items: center;
-          gap: 24px;
-          font-weight: 500;
-          font-size: 14px;
-          line-height: 18px;
-          color: #FFFFFF;
-          background: #010101;
-          padding: 0 24px;
-          .item{
-            display: flex;
-            align-items: center;
-            gap:6px;
-            cursor: pointer;
-          }
-          .line{
-            width: 1px;
-            height: 16px;
-            border-right: 1px solid #4C4C4C;
-          }
-        }
-      }
-    }
-
-    .right {
-      display: flex;
-      flex-wrap: wrap;
-      overflow: auto;
-      gap: 26px;
-      width: 100%;
-      height: 62vh;
-      margin-right: -60px;
-      padding-bottom: 10px ;
-
-      .item {
-        height: 257px;
-        width: 336px;
-        cursor: pointer;
-        border: 1px solid var(--vt-c-border);
-
-        .BG {
-          width: 100%;
-          height: 175px;
-        }
-
-        .infoBox {
-          display: flex;
-          align-items: center;
-          gap: 12px;
-          padding: 0 24px;
-          height: 80px;
-          border-top: none;
-          background: #FFFFFF;
-
-          .avatar {
-            width: 40px;
-            height: 40px;
-            border-radius: 50%;
-          }
-
-          .nameAndType {
-            display: flex;
-            flex-direction: column;
-            gap: 2px;
-
-            .name {
-              font-weight: 700;
-              font-size: 17px;
-              line-height: 22px;
-              color: #010101;
-            }
-
-            .typeBox {
-              display: flex;
-              align-items: center;
-              gap: 10px;
-
-              .type {
-                width: fit-content;
-                //border: 1px solid #b3b3b3;
-                font-weight: 400;
-                font-size: 12px;
-                line-height: 16px;
-                color: #b3b3b3;
-                padding: 0 4px;
-              }
-
-              .type::before {
-                content: "\00B7";
-                margin-right: 5px;
-              }
-            }
-
-          }
-        }
-      }
-
-      //.item:hover {
-      //  box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4);;
-      //}
-    }
-  }
-}
-
-::-webkit-scrollbar {
-  width: 4px; /* 滚动条宽度 */
-}
-
-// /* 滚动条轨道 */
-// ::-webkit-scrollbar-track {
-//   background: #f1f1f1; /* 轨道背景色 */
-// }
-
-/* 滚动条滑块 */
-::-webkit-scrollbar-thumb {
-  background: #888; /* 滑块背景色 */
-}
+<style scoped>
 
-/* 滚动条滑块悬停状态 */
-::-webkit-scrollbar-thumb:hover {
-  background: #555; /* 悬停状态下滑块背景色 */
-}
 </style>

+ 940 - 0
src/views/LayerZeroView.vue

@@ -0,0 +1,940 @@
+<script setup lang="ts">
+//@ts-ignore
+import MetaMaskSDK from '../utils/metamask-sdk.js'
+//@ts-ignore
+import getZksEra from '../utils/getZksEra.js'
+//@ts-ignore
+import getZksLite from '../utils/getZksLite.js'
+//@ts-ignore
+import getZkSyncBridge from '../utils/getZkSyncBridge.js'
+//@ts-ignore
+import getLayerData from '../utils/getLayerData.js'
+import * as echarts from 'echarts';
+import {onMounted, ref} from 'vue';
+import aptosAv from '../project/layer0/aptosAv.png'
+import aptosBg from '../project/layer0/aptosBg.png'
+import stargateAv from '../project/layer0/stargateAv.png'
+import stargateBg from '../project/layer0/stargateBg.png'
+import radiantAv from '../project/layer0/radiantAv.png'
+import radiantBg from '../project/layer0/radiantBg.png'
+import layerzeroAv from '../project/layer0/layerzeroAv.png'
+import layerzeroBg from '../project/layer0/layerzeroBg.png'
+import tapiocaAv from '../project/layer0/tapiocaAv.png'
+import tapiocaBg from '../project/layer0/tapiocaBg.png'
+import omniAv from '../project/layer0/omniAv.png'
+import omniBg from '../project/layer0/omniBg.png'
+import omniteAv from '../project/layer0/omniteAv.png'
+import omniteBg from '../project/layer0/omniteBg.png'
+
+type EChartsOption = echarts.EChartsOption;
+
+onMounted(() => {
+  checkWalletAddress()
+  listeningDisconnect()
+})
+
+
+type dataArrType = {
+  name: string,
+  type: string[],
+  BG: string,
+  avatar: string,
+  url:string
+}[]
+let dataArr: dataArrType = [
+  {
+    name: 'Stargate',
+    type: ['Offical','Bridge'],
+    BG: stargateBg,
+    avatar: stargateAv,
+    url:'https://stargate.finance/'
+  },
+  {
+    name: 'aptos',
+    type: ['Bridge'],
+    BG: aptosBg,
+    avatar: aptosAv,
+    url:'https://theaptosbridge.com/'
+  },
+  {
+    name: 'Radiant Capital',
+    type: ['DeFi'],
+    BG: radiantBg,
+    avatar: radiantAv,
+    url:'https://radiant.capital/'
+  },
+  {
+    name: 'LayerZero Name Service',
+    type: ['Digitalid ID'],
+    BG: layerzeroBg,
+    avatar: layerzeroAv,
+    url:'https://www.lz.domains/'
+  },
+  {
+    name: 'TapiocaDAO',
+    type: ['DeFi'],
+    BG: tapiocaBg,
+    avatar: tapiocaAv,
+    url:'https://www.tapioca.xyz/'
+  },
+  {
+    name: 'Omni X',
+    type: ['NFT', 'Bridge'],
+    BG: omniBg,
+    avatar: omniAv,
+    url:'https://omni-x.io/'
+  },
+  {
+    name: 'Omnite',
+    type: ['NFT'],
+    BG: omniteBg,
+    avatar: omniteAv,
+    url:'https://omnite.io/'
+  },
+]
+
+let MM = ref()//MetaMaskSDK
+let address = ref('')//钱包地址
+let chainId = '0x144'
+const MMSDK = new MetaMaskSDK()
+MM.value = MMSDK.getProvider()
+
+//监听连接断开(通过监听账号的变化判断是否断开连接)
+const listeningDisconnect = () => {
+  MM.value.on('accountsChanged', (accounts: string[]) => {
+    if (accounts.length >= 1) {
+      address.value = accounts[0]
+      connectWallet()
+    } else {
+      address.value = ''
+    }
+  })
+}
+//查询钱包地址
+const checkWalletAddress = async () => {
+  let accounts: string[] = await MM.value.request({method: 'eth_accounts'});//不弹窗
+  address.value = accounts[0]
+  // getMainTx()
+  // getLiteTx()
+  // getMoreInfo()
+  getLayerInfo()
+  // await addChain()
+  // await switchEthereumChain()
+}
+//添加链
+const addChain = () => {
+  MM.value.request({
+    method: 'wallet_addEthereumChain',
+    params: [{
+      chainId: chainId,
+      chainName: 'zkSync Era Mainnet',
+      rpcUrls: ['https://mainnet.era.zksync.io'],
+      blockExplorerUrls: ['https://explorer.zksync.io'],
+      nativeCurrency: {
+        name: 'ETH',
+        symbol: 'ETH',
+        decimals: 18,
+      },
+    }]
+  })
+}
+//切换链
+const switchEthereumChain = () => {
+  MM.value.request({
+    method: 'wallet_switchEthereumChain',
+    params: [{chainId: chainId}],
+  }).then(() => {
+
+  }).catch(() => {
+
+  });
+}
+//连接钱包按钮
+const connectWallet = async () => {
+  let accounts: string[] = await MM.value.request({method: 'eth_requestAccounts'});
+  address.value = accounts[0]
+  // getMainTx()
+  // getLiteTx()
+  // getMoreInfo()
+  getLayerInfo()
+  // await addChain()
+  // await switchEthereumChain()
+}
+//获取主网交易次数
+let mainTx = ref(0)
+const getMainTx = () => {
+  getZksEra(address.value).then(({tx2}:{tx2:number}) => {
+    mainTx.value = tx2
+  })
+}
+//获取lite网交易次数
+let liteTx = ref(0)
+const getLiteTx = () => {
+  getZksLite(address.value).then(({tx1}:{tx1:number}) => {
+    liteTx.value = tx1
+  })
+}
+//获取更多信息
+let amount = ref(0)
+let contract = ref(0)
+let tradingTimeArr = ref()
+let l1Tol2Tx = ref(0)
+let l2Tol1Tx = ref(0)
+const getMoreInfo = () => {
+  getZkSyncBridge(address.value).then((
+      {
+        totalExchangeAmount,
+        contractActivity,
+        overTimeArr,
+        l1Tol2Times,
+        l2Tol1Times
+      }:{
+        totalExchangeAmount:number
+        contractActivity:number
+        overTimeArr:any
+        l1Tol2Times:number
+        l2Tol1Times:number
+      }) => {
+    amount.value = totalExchangeAmount
+    contract.value = contractActivity
+    tradingTimeArr.value = overTimeArr
+    l1Tol2Tx.value = l1Tol2Times
+    l2Tol1Tx.value = l2Tol1Times
+    processTime()
+  })
+}
+//获得layer信息
+let apiKey:any
+let layerInfo = ref<any>({})
+const getLayerInfo = () => {
+  getLayerData(address.value,apiKey).then((
+      {arb, avax, bsc, eth, ftm, matic, metis, op, total, arr}:{arb:string, avax:string, bsc:string, eth:string, ftm:string, matic:string, metis:string, op:string, total:string, arr:any[]}
+  ) => {
+    layerInfo.value = {
+      arb: arb,
+      avax: avax,
+      bsc: bsc,
+      eth: eth,
+      ftm: ftm,
+      matic: matic,
+      metis: metis,
+      op: op,
+      total: total,
+      arr:arr
+    }
+    processTime()
+  })
+}
+//处理时间数据
+const monthArr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+let showMonthNumberArr = ref([0,0,0,0,0,0,0,0,0,0,0,0])
+let showMonthArr = ref()
+const processTime = () => {
+  let nowDate = new Date().toString()
+  let nowDateArr = nowDate.split(' ')
+  let nowMonth = nowDateArr[1]
+  showMonthArr.value = []
+  showMonthArr.value.push(nowMonth)
+  let nowMonthIndex = monthArr.indexOf(nowMonth)
+  const forLoop = () => {
+    for (let i = 11; i !== nowMonthIndex ; i--) {
+      showMonthArr.value.unshift(monthArr[i])
+    }
+  }
+  for (let i = nowMonthIndex; i !== 0 ; i--) {
+    showMonthArr.value.unshift(monthArr[i-1])
+    if (i === 1) {
+      forLoop()
+    }
+  }
+  // if (tradingTimeArr.value){
+  //   tradingTimeArr.value.forEach((item:any) => {
+  //     if(item.balanceChanges[0].from && item.balanceChanges[0].from.toLowerCase() === address.value.toLowerCase()){
+  //       let receivedAt = new Date(Date.parse(item.receivedAt)).toString();
+  //       let strArr = receivedAt.split(' ')
+  //       let month = strArr[1]
+  //       let index = showMonthArr.value.indexOf(month)
+  //       showMonthNumberArr.value[index]++
+  //     }
+  //   })
+  // }
+  if(layerInfo.value.arr){
+    layerInfo.value.arr.forEach((item:any) => {
+      let timestamp = parseFloat(item.timeStamp) * 1000; // 时间戳(以毫秒为单位)
+      let date = new Date(timestamp);
+      let dateString = date.toDateString();
+      let strArr = dateString.split(' ')
+      let month = strArr[1]
+      let index = showMonthArr.value.indexOf(month)
+      showMonthNumberArr.value[index]++
+    })
+  }
+
+  initEcharts()
+
+}
+
+//初始化echarts
+const initEcharts = () => {
+  let chartDom = document.getElementById('echartsBox')!
+  let myChart = echarts.init(chartDom);
+  let option: EChartsOption;
+
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    xAxis: {
+      type: 'category',
+      axisTick: {
+        alignWithLabel: true
+      },
+      data: showMonthArr.value
+    },
+    yAxis: {
+      type: 'value',
+    },
+    series: [
+      {
+        color: '#000000',
+        data: showMonthNumberArr.value,
+        type: 'bar'
+      }
+    ]
+  };
+
+  option && myChart.setOption(option);
+}
+
+//跳转网页
+const toLink = (url:string) => {
+  window.open(url)
+}
+
+const toEmail = (email:string) => {
+  const emailAddress = email; // 替换为你想发送邮件的收件人地址
+  const subject = 'Hello'; // 替换为你想在邮件中设置的主题
+  const body = 'This is the email body.'; // 替换为你想在邮件中设置的内容
+
+  const mailtoUrl = `mailto:${emailAddress}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
+
+  window.open(mailtoUrl);
+}
+
+let sun = ref(true)
+const sunAndMoon = () => {
+  if (sun.value){
+    document.documentElement.style.setProperty('--color-background','#181818')
+    document.documentElement.style.setProperty('--color-text','#f2f2f2')
+    document.documentElement.style.setProperty('--vt-c-border','#555555')
+  }else {
+    document.documentElement.style.setProperty('--color-background','#f2f2f2')
+    document.documentElement.style.setProperty('--color-text','#181818')
+    document.documentElement.style.setProperty('--vt-c-border','#f7f7f7')
+  }
+  sun.value = !sun.value
+}
+
+</script>
+
+<template>
+  <main class="main">
+    <div class="mainBG">
+      <img src="../assets/BG.png" alt="BG">
+    </div>
+    <div class="topBar">
+      <div class="left">
+        <img v-show="!sun" src="../assets/bitflower-white.svg" alt="bitflower">
+        <img v-show="sun" src="../assets/bitflower.svg" alt="logo">
+
+        <div class="navOne">
+          Home
+          <!--          <div class="line"/>-->
+        </div>
+        <div class="nav">
+          NFT
+          <!--          <div class="line"/>-->
+        </div>
+        <div class="nav">
+          Query
+          <div class="line"/>
+        </div>
+      </div>
+      <!--      <div class="mid">-->
+      <!--        Blossom your Web3 Trip ✈-->
+      <!--      </div>-->
+      <div class="right">
+        <img v-show="!sun" @click="sunAndMoon" src="../assets/sun-fill.svg" alt="sun-fill">
+        <img v-show="sun" @click="sunAndMoon" src="../assets/moon-clear-fill.svg" alt="moon-clear-fill">
+        <div class="button" v-show="!address" @click="connectWallet">
+          <img src="../assets/git-commit-line.svg" alt="commit">
+          Connect Wallet
+        </div>
+        <div class="connect" v-if="address">
+          <img src="../assets/git-commit-line-black.svg" alt="commit">
+          {{ address.slice(0, 8) }}...{{ address.slice(-4) }}
+        </div>
+      </div>
+    </div>
+    <div class="chainBox">
+      <div class="item" style="cursor: pointer" @click="toLink('https://zksync.biflower.cc')">
+        zkSync
+      </div>
+      <div class="item">
+        Layer Zero
+        <div class="line"></div>
+      </div>
+      <div class="item">
+        StarkNet
+      </div>
+    </div>
+    <div class="dataColumn">
+      <div class="item">
+        <div class="top">
+          <div class="img">
+            <img v-show="!sun" src="../assets/layerZero/layerZero-white.svg" alt="group1">
+            <img v-show="sun" src="../assets/layerZero/layerZero.svg" alt="group1">
+          </div>
+          <div class="title">
+            Total Transactions
+            <el-popover
+                placement="bottom"
+                :width="230"
+                trigger="hover"
+                effect="dark"
+            >
+              <template #reference>
+                <img src="../assets/info.svg" alt="info">
+              </template>
+              <div class="popoverText">
+                Number of protocolsinteracted
+              </div>
+              <div class="popoverText">
+                with out of allavailable protocols
+              </div>
+            </el-popover>
+          </div>
+        </div>
+        <div class="number">
+          {{ layerInfo.total || 0 }}
+        </div>
+      </div>
+      <div class="item" style="gap:6px;">
+        <div class="top">
+          <div class="img">
+            <img v-show="!sun" src="../assets/layerZero/publicChain-white.svg" alt="group1">
+            <img v-show="sun" src="../assets/layerZero/publicChain.svg" alt="group1">
+          </div>
+        </div>
+        <div class="publicChainBox">
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/ETH.svg" alt="ETH">
+              ETH
+            </div>
+            <div class="number">
+              {{ layerInfo.eth || 0 }}
+            </div>
+          </div>
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/MATIC.svg" alt="ETH">
+              MATIC
+            </div>
+            <div class="number">
+              {{ layerInfo.matic || 0 }}
+            </div>
+          </div>
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/BSC.svg" alt="ETH">
+              BSC
+            </div>
+            <div class="number">
+              {{ layerInfo.bsc || 0 }}
+            </div>
+          </div>
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/ARB.svg" alt="ETH">
+              ARB
+            </div>
+            <div class="number">
+              {{ layerInfo.arb || 0 }}
+            </div>
+          </div>
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/OP.svg" alt="ETH">
+              OP
+            </div>
+            <div class="number">
+              {{ layerInfo.op || 0 }}
+            </div>
+          </div>
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/AVAX.svg" alt="ETH">
+              AVAX
+            </div>
+            <div class="number">
+              {{ layerInfo.avax || 0 }}
+            </div>
+          </div>
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/FTM.svg" alt="ETH">
+              FTM
+            </div>
+            <div class="number">
+              {{ layerInfo.ftm || 0 }}
+            </div>
+          </div>
+          <div class="publicChainItem">
+            <div class="title">
+              <img src="../assets/layerZero/METIS.svg" alt="ETH">
+              METIS
+            </div>
+            <div class="number">
+              {{ layerInfo.metis || 0 }}
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="primary">
+      <div class="left">
+        <div class="echarts">
+          <div class="title">
+            Transactions Over Time
+            <el-popover
+                placement="right"
+                :width="240"
+                trigger="hover"
+                effect="dark"
+            >
+              <template #reference>
+                <img src="../assets/info.svg" alt="info">
+              </template>
+              <div class="popoverText">
+                Number of transactions permonth
+              </div>
+            </el-popover>
+          </div>
+          <div class="echartsBox" id="echartsBox">
+
+          </div>
+        </div>
+        <div class="disclaimer">
+          <img v-show="!sun" src="../assets/disclaimer-white.svg" alt="disclaimer">
+          <img v-show="sun" src="../assets/disclaimer.svg" alt="disclaimer">
+          <div class="description">
+            The list of dApps is for informational purposes only. It is not a testimony of the security or reliability
+            of any dApp. Furthermore, most dApps are currently in alpha stage and their code is not audited. You are
+            encouraged to do your own research (DYOR) before interacting with, or investing in any dApps. This should
+            not be considered financial or investment advice.
+          </div>
+          <div class="contact">
+            <div class="item" @click="toEmail('bitflower.web3@gmail.com')">
+              <img src="../assets/mail-open-line.svg" alt="mail">
+              E-mail
+            </div>
+            <div class="line"/>
+            <div class="item" @click="toLink('https://t.me/bitflowersupport')">
+              <img src="../assets/telegram-line.svg" alt="telegram">
+              Telegram
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="right">
+        <div class="item" @click="toLink(item.url)" v-for="item in dataArr">
+          <div class="BG">
+            <img class="BG" :src="item.BG" alt="BG">
+          </div>
+          <div class="infoBox">
+            <div class="avatar">
+              <img class="avatar" :src="item.avatar" alt="avatar">
+            </div>
+            <div class="nameAndType">
+              <div class="name">
+                {{ item.name }}
+              </div>
+              <div class="typeBox">
+                <div class="type" v-for="item1 in item.type">
+                  {{ item1 }}
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </main>
+</template>
+
+<style lang="scss">
+.main {
+  width: 1440px;
+  height: 100%;
+  margin: auto;
+  border: 1px solid var(--vt-c-border);
+  border-top: none;
+  border-bottom: none;
+  padding: 30px 60px;
+  .mainBG{
+    position: absolute;
+    top: 0;
+    z-index: -1;
+  }
+  .topBar {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 60px 25px;
+    margin: 0 -60px;
+    border-bottom: 1px solid var(--vt-c-border);
+    .left{
+      display: flex;
+      align-items: center;
+      .nav{
+        font-family: HONOR Sans CN;
+        font-size: 21px;
+        font-style: normal;
+        font-weight: 700;
+        line-height: normal;
+        padding: 0 60px;
+        height: 100px;
+        display: flex;
+        align-items: center;
+        margin-bottom: -25px;
+        margin-top: -30px;
+        border-right: 1px solid var(--vt-c-border);
+        position: relative;
+        .line{
+          position: absolute;
+          width: 100%;
+          height: 10px;
+          background: var(--color-text);
+          left: 0;
+          bottom: 0;
+        }
+      }
+      .navOne{
+        font-family: HONOR Sans CN;
+        font-size: 21px;
+        font-style: normal;
+        font-weight: 700;
+        line-height: normal;
+        padding: 0 60px;
+        height: 100px;
+        display: flex;
+        align-items: center;
+        margin-bottom: -25px;
+        margin-top: -30px;
+        border-right: 1px solid var(--vt-c-border);
+        margin-left: 57px;
+        border-left: 1px solid var(--vt-c-border);
+        position: relative;
+        .line{
+          position: absolute;
+          width: 100%;
+          height: 10px;
+          background: var(--color-text);
+          left: 0;
+          bottom: 0;
+        }
+      }
+    }
+    .mid{
+      font-weight: 400;
+      font-size: 15px;
+      line-height: 21px;
+      font-family: 'Chillax';
+      text-transform: uppercase;
+    }
+    .right {
+      display: flex;
+      align-items: center;
+      gap:40px;
+      cursor: pointer;
+
+      .button {
+        width: fit-content;
+        height: 44px;
+        display: flex;
+        align-items: center;
+        gap: 6px;
+        background: #010101;
+        padding: 0 24px;
+        font-weight: 500;
+        font-size: 15px;
+        line-height: 20px;
+        color: #FFFFFF;
+        cursor: pointer;
+      }
+
+      .connect {
+        width: fit-content;
+        height: 44px;
+        display: flex;
+        align-items: center;
+        gap: 6px;
+        background: #FFFFFF;
+        border: 1px solid #010101;
+        border-radius: 30px;
+        padding: 0 24px;
+        font-weight: 500;
+        font-size: 15px;
+        line-height: 20px;
+        color: #010101;
+      }
+    }
+  }
+  .chainBox{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    margin: 0 -60px;
+    .item{
+      padding: 24px 65px;
+      border-right: 1px solid var(--vt-c-border);
+      font-family: HONOR Sans CN;
+      font-size: 15px;
+      font-style: normal;
+      font-weight: 700;
+      line-height: normal;
+      position: relative;
+      .line{
+        position: absolute;
+        width: 60px;
+        height: 4px;
+        background: var(--color-text);
+        left: 0;
+        right: 0;
+        margin: auto;
+        bottom: 0;
+      }
+    }
+  }
+  .dataColumn {
+    display: flex;
+    align-items: center;
+    //justify-content: space-between;
+    padding: 60px;
+    border-bottom: 1px solid var(--vt-c-border);
+    border-top: 1px solid var(--vt-c-border);
+    margin: 0 -60px;
+    position: relative;
+    .item {
+      width: 260px;
+      display: flex;
+      flex-direction: column;
+      gap: 20px;
+
+      .top {
+        display: flex;
+        flex-direction: column;
+        gap: 6px;
+
+        .img {
+          height: 16px;
+        }
+      }
+      .publicChainBox{
+        display: flex;
+        align-items: center;
+        gap:88px;
+        .publicChainItem{
+          display: flex;
+          flex-direction: column;
+          gap:20px;
+        }
+      }
+      .title {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+        font-weight: 400;
+        font-size: 14px;
+        line-height: 18px;
+        //color: #010101;
+        font-family: 'HONOR Sans CN';
+        .popoverText{
+          font-weight: 400;
+          font-size: 12px;
+          line-height: 24px;
+        }
+      }
+
+      .number {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+        font-weight: 700;
+        font-size: 26px;
+        line-height: 34px;
+        //color: #010101;
+      }
+    }
+  }
+
+  .primary {
+    display: flex;
+    gap: 60px;
+    margin-top: 60px;
+
+    .left {
+      display: flex;
+      flex-direction: column;
+
+      .echarts {
+        .title {
+          display: flex;
+          align-items: center;
+          gap: 8px;
+          font-weight: 700;
+          font-size: 14px;
+          line-height: 18px;
+          //color: #010101;
+        }
+
+        .echartsBox {
+          height: 360px;
+          width: 560px;
+        }
+      }
+
+      .disclaimer {
+        width: 558px;
+        height: 246px;
+        border: 1px solid #010101;
+        padding: 24px;
+
+        .description {
+          margin-top: 8px;
+          margin-bottom: 28px;
+          font-weight: 400;
+          font-size: 12px;
+          line-height: 24px;
+          color: #808080;
+        }
+
+        .contact {
+          width: fit-content;
+          height: 44px;
+          display: flex;
+          align-items: center;
+          gap: 24px;
+          font-weight: 500;
+          font-size: 14px;
+          line-height: 18px;
+          color: #FFFFFF;
+          background: #010101;
+          padding: 0 24px;
+          .item{
+            display: flex;
+            align-items: center;
+            gap:6px;
+            cursor: pointer;
+          }
+          .line{
+            width: 1px;
+            height: 16px;
+            border-right: 1px solid #4C4C4C;
+          }
+        }
+      }
+    }
+
+    .right {
+      display: flex;
+      flex-wrap: wrap;
+      overflow: auto;
+      gap: 26px;
+      width: 100%;
+      height: 62vh;
+      margin-right: -60px;
+
+      .item {
+        height: 256px;
+        width: 336px;
+        cursor: pointer;
+        .BG {
+          width: 100%;
+          height: 175px;
+        }
+
+        .infoBox {
+          display: flex;
+          align-items: center;
+          gap: 12px;
+          padding: 0 24px;
+          height: 80px;
+          border: 1px solid #010101;
+          border-top: none;
+          background: #FFFFFF;
+
+          .avatar {
+            width: 40px;
+            height: 40px;
+            border-radius: 50%;
+          }
+
+          .nameAndType {
+            display: flex;
+            flex-direction: column;
+            gap: 2px;
+
+            .name {
+              font-weight: 700;
+              font-size: 17px;
+              line-height: 22px;
+              color: #010101;
+            }
+
+            .typeBox {
+              display: flex;
+              align-items: center;
+              gap: 10px;
+
+              .type {
+                width: fit-content;
+                border: 1px solid #b3b3b3;
+                font-weight: 400;
+                font-size: 12px;
+                line-height: 16px;
+                color: #b3b3b3;
+                padding: 0 4px;
+              }
+            }
+
+          }
+        }
+      }
+    }
+  }
+}
+
+::-webkit-scrollbar {
+  width: 4px; /* 滚动条宽度 */
+}
+
+// /* 滚动条轨道 */
+// ::-webkit-scrollbar-track {
+//   background: #f1f1f1; /* 轨道背景色 */
+// }
+
+/* 滚动条滑块 */
+::-webkit-scrollbar-thumb {
+  background: #888; /* 滑块背景色 */
+}
+
+/* 滚动条滑块悬停状态 */
+::-webkit-scrollbar-thumb:hover {
+  background: #555; /* 悬停状态下滑块背景色 */
+}
+</style>

+ 941 - 0
src/views/ZksyncView.vue

@@ -0,0 +1,941 @@
+<script setup lang="ts">
+//@ts-ignore
+import MetaMaskSDK from '../utils/metamask-sdk.js'
+//@ts-ignore
+import getZksEra from '../utils/getZksEra.js'
+//@ts-ignore
+import getZksLite from '../utils/getZksLite.js'
+//@ts-ignore
+import getZkSyncBridge from '../utils/getZkSyncBridge.js'
+import * as echarts from 'echarts';
+import {onMounted, ref} from 'vue';
+import balancerBg from '../project/balancer/balancerBg.png'
+import balancerAv from '../project/balancer/balancerAv.png'
+import argentBg from '../project/argent/argentBg.png'
+import argentAv from '../project/argent/argentAv.png'
+import ontoBg from '../project/onto/ontoBg.png'
+import ontoAv from '../project/onto/ontoAv.png'
+import zerionBg from '../project/zerion/zerionBg.png'
+import zerionAv from '../project/zerion/zerionAv.png'
+import zksEraBridgeAv from '../project/zksEraBridge/zksEraBridgeAv.png'
+import zksEraBridgeBg from '../project/zksEraBridge/zksEraBridgeBg.png'
+import zksLiteBridgeBg from '../project/zksLiteBridge/zksLiteBridgeBg.png'
+import zksLiteBridgeAv from '../project/zksLiteBridge/zksLiteBridgeAv.png'
+import orbiterAv from '../project/orbiter/orbiterAv.png'
+import orbiterBg from '../project/orbiter/orbiterBg.png'
+import muteAv from '../project/mute/muteAv.png'
+import muteBg from '../project/mute/muteBg.png'
+import syncswapBg from '../project/syncswap/syncswapBg.png'
+import syncswapAv from '../project/syncswap/syncswapAv.png'
+import getcoinBg from '../project/getcoin/getcoinBg.png'
+import getcoinAv from '../project/getcoin/getcoinAv.png'
+import router from "@/router";
+
+type EChartsOption = echarts.EChartsOption;
+
+onMounted(() => {
+  checkWalletAddress()
+  listeningDisconnect()
+})
+
+
+type dataArrType = {
+  name: string,
+  type: string[],
+  BG: string,
+  avatar: string,
+  url:string
+}[]
+let dataArr: dataArrType = [
+  {
+    name: 'zks-era bridge',
+    type: ['OFFICAL','BRIDGE'],
+    BG: zksEraBridgeBg,
+    avatar: zksEraBridgeAv,
+    url:'https://bridge.zksync.io/'
+  },
+  {
+    name: 'zks-lite bridge',
+    type: ['OFFICAL','BRIDGE'],
+    BG: zksLiteBridgeBg,
+    avatar: zksLiteBridgeAv,
+    url:'https://lite.zksync.io/transaction/deposit'
+  },
+  {
+    name: 'Orbiter',
+    type: ['ERA', 'SWAP'],
+    BG: orbiterBg,
+    avatar: orbiterAv,
+    url:'https://www.orbiter.finance/'
+  },
+  {
+    name: 'Mute',
+    type: ['ERA', 'DEFI', 'SWAP'],
+    BG: muteBg,
+    avatar: muteAv,
+    url:'https://app.mute.io/swap'
+  },
+  {
+    name: 'Syncswap',
+    type: ['ERA', 'SWAP'],
+    BG: syncswapBg,
+    avatar: syncswapAv,
+    url:'https://syncswap.xyz/'
+  },
+  {
+    name: 'Gitcoin',
+    type: ['DEFI', 'SWAP'],
+    BG: getcoinBg,
+    avatar: getcoinAv,
+    url:'https://bounties.gitcoin.co/'
+  },
+]
+
+let MM = ref()//MetaMaskSDK
+let address = ref('')//钱包地址
+let chainId = '0x144'
+const MMSDK = new MetaMaskSDK()
+MM.value = MMSDK.getProvider()
+
+//监听连接断开(通过监听账号的变化判断是否断开连接)
+const listeningDisconnect = () => {
+  MM.value.on('accountsChanged', (accounts: string[]) => {
+    if (accounts.length >= 1) {
+      address.value = accounts[0]
+      connectWallet()
+    } else {
+      address.value = ''
+    }
+  })
+}
+//查询钱包地址
+const checkWalletAddress = async () => {
+  let accounts: string[] = await MM.value.request({method: 'eth_accounts'});//不弹窗
+  address.value = accounts[0]
+  getMainTx()
+  getLiteTx()
+  getMoreInfo()
+  await addChain()
+  await switchEthereumChain()
+}
+//添加链
+const addChain = () => {
+  MM.value.request({
+    method: 'wallet_addEthereumChain',
+    params: [{
+      chainId: chainId,
+      chainName: 'zkSync Era Mainnet',
+      rpcUrls: ['https://mainnet.era.zksync.io'],
+      blockExplorerUrls: ['https://explorer.zksync.io'],
+      nativeCurrency: {
+        name: 'ETH',
+        symbol: 'ETH',
+        decimals: 18,
+      },
+    }]
+  })
+}
+//切换链
+const switchEthereumChain = () => {
+  MM.value.request({
+    method: 'wallet_switchEthereumChain',
+    params: [{chainId: chainId}],
+  }).then(() => {
+
+  }).catch(() => {
+
+  });
+}
+//连接钱包按钮
+const connectWallet = async () => {
+  let accounts: string[] = await MM.value.request({method: 'eth_requestAccounts'});
+  address.value = accounts[0]
+  getMainTx()
+  getLiteTx()
+  getMoreInfo()
+  await addChain()
+  await switchEthereumChain()
+}
+//获取主网交易次数
+let mainTx = ref(0)
+const getMainTx = () => {
+  getZksEra(address.value).then(({tx2}:{tx2:number}) => {
+    mainTx.value = tx2
+  })
+}
+//获取lite网交易次数
+let liteTx = ref(0)
+const getLiteTx = () => {
+  getZksLite(address.value).then(({tx1}:{tx1:number}) => {
+    liteTx.value = tx1
+  })
+}
+//获取更多信息
+let amount = ref(0)
+let contract = ref(0)
+let tradingTimeArr = ref()
+let l1Tol2Tx = ref(0)
+let l2Tol1Tx = ref(0)
+const getMoreInfo = () => {
+  getZkSyncBridge(address.value).then((
+      {
+          totalExchangeAmount,
+          contractActivity,
+          overTimeArr,
+          l1Tol2Times,
+          l2Tol1Times
+      }:{
+        totalExchangeAmount:number
+        contractActivity:number
+        overTimeArr:any
+        l1Tol2Times:number
+        l2Tol1Times:number
+      }) => {
+    amount.value = totalExchangeAmount
+    contract.value = contractActivity
+    tradingTimeArr.value = overTimeArr
+    l1Tol2Tx.value = l1Tol2Times
+    l2Tol1Tx.value = l2Tol1Times
+    processTime()
+  })
+}
+//处理时间数据
+const monthArr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+let showMonthNumberArr = ref([0,0,0,0,0,0,0,0,0,0,0,0])
+let showMonthArr = ref()
+const processTime = () => {
+  let nowDate = new Date().toString()
+  let nowDateArr = nowDate.split(' ')
+  let nowMonth = nowDateArr[1]
+  showMonthArr.value = []
+  showMonthArr.value.push(nowMonth)
+  let nowMonthIndex = monthArr.indexOf(nowMonth)
+  const forLoop = () => {
+    for (let i = 11; i !== nowMonthIndex ; i--) {
+      showMonthArr.value.unshift(monthArr[i])
+    }
+  }
+  for (let i = nowMonthIndex; i !== 0 ; i--) {
+    showMonthArr.value.unshift(monthArr[i-1])
+    if (i === 1) {
+      forLoop()
+    }
+  }
+  if (tradingTimeArr.value){
+    tradingTimeArr.value.forEach((item:any) => {
+      if(item.balanceChanges[0].from && item.balanceChanges[0].from.toLowerCase() === address.value.toLowerCase()){
+        let receivedAt = new Date(Date.parse(item.receivedAt)).toString();
+        let strArr = receivedAt.split(' ')
+        let month = strArr[1]
+        let index = showMonthArr.value.indexOf(month)
+        showMonthNumberArr.value[index]++
+      }
+    })
+  }
+
+  initEcharts()
+
+}
+
+//初始化echarts
+const initEcharts = () => {
+  let chartDom = document.getElementById('echartsBox')!
+  let myChart = echarts.init(chartDom);
+  let option: EChartsOption;
+
+  option = {
+    tooltip: {
+      trigger: 'axis',
+      axisPointer: {
+        type: 'shadow'
+      }
+    },
+    xAxis: {
+      type: 'category',
+      axisTick: {
+        alignWithLabel: true
+      },
+      data: showMonthArr.value
+    },
+    yAxis: {
+      type: 'value',
+    },
+    series: [
+      {
+        color: '#000000',
+        data: showMonthNumberArr.value,
+        type: 'bar'
+      }
+    ]
+  };
+
+  option && myChart.setOption(option);
+}
+
+//跳转网页
+const toLink = (url:string) => {
+  window.open(url)
+}
+
+const toPage = (url:string) => {
+  router.push(url)
+}
+const toEmail = (email:string) => {
+  const emailAddress = email; // 替换为你想发送邮件的收件人地址
+  const subject = 'Hello'; // 替换为你想在邮件中设置的主题
+  const body = 'This is the email body.'; // 替换为你想在邮件中设置的内容
+
+  const mailtoUrl = `mailto:${emailAddress}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
+
+  window.open(mailtoUrl);
+}
+
+let sun = ref(true)
+const sunAndMoon = () => {
+  if (sun.value){
+    document.documentElement.style.setProperty('--color-background','#181818')
+    document.documentElement.style.setProperty('--color-text','#f2f2f2')
+    document.documentElement.style.setProperty('--vt-c-border','#555555')
+  }else {
+    document.documentElement.style.setProperty('--color-background','#f2f2f2')
+    document.documentElement.style.setProperty('--color-text','#181818')
+    document.documentElement.style.setProperty('--vt-c-border','#f7f7f7')
+
+  }
+  sun.value = !sun.value
+
+}
+</script>
+
+<template>
+  <main class="main">
+    <div class="mainBG">
+      <img src="../assets/BG.png" alt="BG">
+    </div>
+    <div class="topBar">
+      <div class="left">
+        <img v-show="!sun" src="../assets/bitflower-white.svg" alt="bitflower">
+        <img v-show="sun" src="../assets/bitflower.svg" alt="logo">
+
+        <div class="navOne">
+          Home
+<!--          <div class="line"/>-->
+        </div>
+        <div class="nav">
+          NFT
+<!--          <div class="line"/>-->
+        </div>
+        <div class="nav">
+          Query
+          <div class="line"/>
+        </div>
+      </div>
+<!--      <div class="mid">-->
+<!--        Blossom your Web3 Trip ✈-->
+<!--      </div>-->
+      <div class="right">
+        <img v-show="!sun" @click="sunAndMoon" src="../assets/sun-fill.svg" alt="sun-fill">
+        <img v-show="sun" @click="sunAndMoon" src="../assets/moon-clear-fill.svg" alt="moon-clear-fill">
+        <div class="button" v-show="!address" @click="connectWallet">
+          <img src="../assets/git-commit-line.svg" alt="commit">
+          Connect Wallet
+        </div>
+        <div class="connect" v-if="address">
+          <img src="../assets/git-commit-line-black.svg" alt="commit">
+          {{ address.slice(0, 8) }}...{{ address.slice(-4) }}
+        </div>
+      </div>
+    </div>
+    <div class="chainBox">
+      <div class="item">
+        zkSync
+        <div class="line"></div>
+      </div>
+      <div class="item" style="cursor: pointer" @click="toLink('https://layer0.biflower.cc')">
+        Layer Zero
+      </div>
+      <div class="item">
+        StarkNet
+      </div>
+    </div>
+    <div class="dataColumn">
+      <div class="item">
+        <div class="top">
+          <div class="img">
+            <img v-show="!sun" src="../assets/group1-white.svg" alt="group1">
+            <img v-show="sun" src="../assets/group1.svg" alt="group1">
+          </div>
+          <div class="title">
+            Protocols lnteraction
+            <el-popover
+                placement="bottom"
+                :width="230"
+                trigger="hover"
+                effect="dark"
+            >
+              <template #reference>
+                <img src="../assets/info.svg" alt="info">
+              </template>
+              <div class="popoverText">
+                Number of protocolsinteracted
+              </div>
+              <div class="popoverText">
+                with out of allavailable protocols
+              </div>
+            </el-popover>
+          </div>
+        </div>
+        <div class="number">
+          {{ contract }}
+        </div>
+      </div>
+      <div class="line" style="left:270px">
+
+      </div>
+      <div class="item">
+        <div class="top">
+          <div class="img">
+            <img v-show="!sun" class="img" src="../assets/group3-white.svg" alt="group2">
+            <img v-show="sun" class="img" src="../assets/group3.svg" alt="group2">
+          </div>
+          <div class="title">
+            Total Transactions
+            <el-popover
+                placement="bottom"
+                :width="250"
+                trigger="hover"
+                effect="dark"
+            >
+              <template #reference>
+                <img src="../assets/info.svg" alt="info">
+              </template>
+              <div class="popoverText">
+                Total zkSync lite
+              </div>
+              <div class="popoverText">
+                transactions issuedfrom the account
+              </div>
+            </el-popover>
+          </div>
+        </div>
+        <div class="number">
+          {{ liteTx }}
+          <img @click="toLink('https://zkscan.io/')" style="cursor: pointer" src="../assets/arrow-right-up-line.svg" alt="arrow">
+        </div>
+      </div>
+      <div class="item">
+        <div class="top">
+          <div class="img">
+            <img v-show="!sun" class="img" src="../assets/group2-white.svg" alt="group2">
+            <img v-show="sun" class="img" src="../assets/group2.svg" alt="group2">
+          </div>
+          <div class="title">
+            Total Transactions
+            <el-popover
+                placement="bottom"
+                :width="250"
+                trigger="hover"
+                effect="dark"
+            >
+              <template #reference>
+                <img src="../assets/info.svg" alt="info">
+              </template>
+              <div class="popoverText">
+                Total zkSync era
+              </div>
+              <div class="popoverText">
+                transactions issuedfrom the account
+              </div>
+            </el-popover>
+          </div>
+        </div>
+        <div class="number">
+          {{ mainTx }}
+          <img @click="toLink('https://explorer.zksync.io/')" style="cursor: pointer" src="../assets/arrow-right-up-line.svg" alt="arrow">
+        </div>
+      </div>
+      <div class="item" style="height: 94px">
+        <div class="top">
+          <div class="img">
+            <img v-show="!sun" class="img" src="../assets/official-bridge-white.svg" alt="group2">
+            <img v-show="sun" class="img" src="../assets/official-bridge-black.svg" alt="group2">
+          </div>
+          <div style="display: flex;gap:40px">
+            <div style="display: flex;flex-direction: column;gap:20px">
+              <img v-show="!sun" src="../assets/L1-To-L2-white.svg" alt="To">
+              <img v-show="sun" src="../assets/L1-To-L2.svg" alt="To">
+              <div class="number">
+                {{ l1Tol2Tx }}
+              </div>
+            </div>
+            <div style="display: flex;flex-direction: column;gap:20px">
+              <img v-show="!sun" src="../assets/L2-To-L1-white.svg" alt="To">
+              <img v-show="sun" src="../assets/L2-To-L1.svg" alt="To">
+              <div class="number">
+                {{ l2Tol1Tx }}
+              </div>
+            </div>
+          </div>
+        </div>
+
+      </div>
+      <div class="line" style="right:370px">
+
+      </div>
+      <div class="item">
+        <div class="top">
+          <div class="img">
+            <img class="img" src="../assets/group4.svg" alt="group2">
+          </div>
+          <div class="title">
+            Total amount spent
+          </div>
+        </div>
+        <div class="number">
+          {{ amount }} USDT
+        </div>
+      </div>
+    </div>
+    <div class="primary">
+      <div class="left">
+        <div class="echarts">
+          <div class="title">
+            Transactions Over Time
+            <el-popover
+                placement="right"
+                :width="240"
+                trigger="hover"
+                effect="dark"
+            >
+              <template #reference>
+                <img src="../assets/info.svg" alt="info">
+              </template>
+              <div class="popoverText">
+                Number of transactions permonth
+              </div>
+            </el-popover>
+          </div>
+          <div class="echartsBox" id="echartsBox">
+
+          </div>
+        </div>
+        <div class="disclaimer">
+          <img v-show="!sun" src="../assets/disclaimer-white.svg" alt="disclaimer">
+          <img v-show="sun" src="../assets/disclaimer.svg" alt="disclaimer">
+          <div class="description">
+            The list of dApps is for informational purposes only. It is not a testimony of the security or reliability
+            of any dApp. Furthermore, most dApps are currently in alpha stage and their code is not audited. You are
+            encouraged to do your own research (DYOR) before interacting with, or investing in any dApps. This should
+            not be considered financial or investment advice.
+          </div>
+          <div class="contact">
+            <div class="item" @click="toEmail('bitflower.web3@gmail.com')">
+              <img src="../assets/mail-open-line.svg" alt="mail">
+              E-mail
+            </div>
+            <div class="line"/>
+            <div class="item" @click="toLink('https://t.me/bitflowersupport')">
+              <img src="../assets/telegram-line.svg" alt="telegram">
+              Telegram
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="right">
+        <div class="item" @click="toLink(item.url)" v-for="item in dataArr">
+          <div class="BG">
+            <img class="BG" :src="item.BG" alt="BG">
+          </div>
+          <div class="infoBox">
+            <div class="avatar">
+              <img class="avatar" :src="item.avatar" alt="avatar">
+            </div>
+            <div class="nameAndType">
+              <div class="name">
+                {{ item.name }}
+              </div>
+              <div class="typeBox">
+                <div class="type" v-for="item1 in item.type">
+                  {{ item1 }}
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </main>
+</template>
+
+<style lang="scss">
+.main {
+  width: 1440px;
+  height: 100%;
+  margin: auto;
+  border: 1px solid var(--vt-c-border);
+  border-top: none;
+  border-bottom: none;
+  padding: 30px 60px;
+  .mainBG{
+    position: absolute;
+    top: 0;
+    z-index: -1;
+  }
+  .topBar {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 60px 25px;
+    margin: 0 -60px;
+    border-bottom: 1px solid var(--vt-c-border);
+    .left{
+      display: flex;
+      align-items: center;
+      .nav{
+        font-family: HONOR Sans CN;
+        font-size: 21px;
+        font-style: normal;
+        font-weight: 700;
+        line-height: normal;
+        padding: 0 60px;
+        height: 100px;
+        display: flex;
+        align-items: center;
+        margin-bottom: -25px;
+        margin-top: -30px;
+        border-right: 1px solid var(--vt-c-border);
+        position: relative;
+        .line{
+          position: absolute;
+          width: 100%;
+          height: 10px;
+          background: var(--color-text);
+          left: 0;
+          bottom: 0;
+        }
+      }
+      .navOne{
+        font-family: HONOR Sans CN;
+        font-size: 21px;
+        font-style: normal;
+        font-weight: 700;
+        line-height: normal;
+        padding: 0 60px;
+        height: 100px;
+        display: flex;
+        align-items: center;
+        margin-bottom: -25px;
+        margin-top: -30px;
+        border-right: 1px solid var(--vt-c-border);
+        margin-left: 57px;
+        border-left: 1px solid var(--vt-c-border);
+        position: relative;
+        .line{
+          position: absolute;
+          width: 100%;
+          height: 10px;
+          background: var(--color-text);
+          left: 0;
+          bottom: 0;
+        }
+      }
+    }
+    .mid{
+      font-weight: 400;
+      font-size: 15px;
+      line-height: 21px;
+      font-family: 'Chillax';
+      text-transform: uppercase;
+    }
+    .right {
+      display: flex;
+      align-items: center;
+      gap:40px;
+      cursor: pointer;
+
+      .button {
+        width: fit-content;
+        height: 44px;
+        display: flex;
+        align-items: center;
+        gap: 6px;
+        background: #010101;
+        padding: 0 24px;
+        font-weight: 500;
+        font-size: 15px;
+        line-height: 20px;
+        color: #FFFFFF;
+        cursor: pointer;
+      }
+
+      .connect {
+        width: fit-content;
+        height: 44px;
+        display: flex;
+        align-items: center;
+        gap: 6px;
+        background: #FFFFFF;
+        border: 1px solid #010101;
+        border-radius: 30px;
+        padding: 0 24px;
+        font-weight: 500;
+        font-size: 15px;
+        line-height: 20px;
+        color: #010101;
+      }
+    }
+  }
+  .chainBox{
+    width: 100%;
+    display: flex;
+    align-items: center;
+    margin: 0 -60px;
+    .item{
+      padding: 24px 65px;
+      border-right: 1px solid var(--vt-c-border);
+      font-family: HONOR Sans CN;
+      font-size: 15px;
+      font-style: normal;
+      font-weight: 700;
+      line-height: normal;
+      position: relative;
+      .line{
+        position: absolute;
+        width: 60px;
+        height: 4px;
+        background: var(--color-text);
+        left: 0;
+        right: 0;
+        margin: auto;
+        bottom: 0;
+      }
+    }
+  }
+  .dataColumn {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 60px;
+    border-bottom: 1px solid var(--vt-c-border);
+    border-top: 1px solid var(--vt-c-border);
+    margin: 0 -60px;
+    position: relative;
+
+    .item {
+      width: 330px;
+      display: flex;
+      flex-direction: column;
+      gap: 20px;
+
+      .top {
+        display: flex;
+        flex-direction: column;
+        gap: 6px;
+
+        .img {
+          height: 16px;
+        }
+
+        .title {
+          display: flex;
+          align-items: center;
+          gap: 8px;
+          font-weight: 400;
+          font-size: 14px;
+          line-height: 18px;
+          //color: #010101;
+          font-family: 'HONOR Sans CN';
+          .popoverText{
+            font-weight: 400;
+            font-size: 12px;
+            line-height: 24px;
+          }
+        }
+      }
+
+      .number {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+        font-weight: 700;
+        font-size: 26px;
+        line-height: 34px;
+        //color: #010101;
+      }
+    }
+
+    .line {
+      width: 1px;
+      height: 100%;
+      border-right: 1px solid var(--vt-c-border);
+      position: absolute;
+    }
+  }
+
+  .primary {
+    display: flex;
+    gap: 60px;
+    margin-top: 60px;
+
+    .left {
+      display: flex;
+      flex-direction: column;
+
+      .echarts {
+        .title {
+          display: flex;
+          align-items: center;
+          gap: 8px;
+          font-weight: 700;
+          font-size: 14px;
+          line-height: 18px;
+          //color: #010101;
+        }
+
+        .echartsBox {
+          height: 360px;
+          width: 560px;
+        }
+      }
+
+      .disclaimer {
+        width: 558px;
+        height: 246px;
+        border: 1px solid #010101;
+        padding: 24px;
+
+        .description {
+          margin-top: 8px;
+          margin-bottom: 28px;
+          font-weight: 400;
+          font-size: 12px;
+          line-height: 24px;
+          color: #808080;
+        }
+
+        .contact {
+          width: fit-content;
+          height: 44px;
+          display: flex;
+          align-items: center;
+          gap: 24px;
+          font-weight: 500;
+          font-size: 14px;
+          line-height: 18px;
+          color: #FFFFFF;
+          background: #010101;
+          padding: 0 24px;
+          .item{
+            display: flex;
+            align-items: center;
+            gap:6px;
+            cursor: pointer;
+          }
+          .line{
+            width: 1px;
+            height: 16px;
+            border-right: 1px solid #4C4C4C;
+          }
+        }
+      }
+    }
+
+    .right {
+      display: flex;
+      flex-wrap: wrap;
+      overflow: auto;
+      gap: 26px;
+      width: 100%;
+      height: 62vh;
+      margin-right: -60px;
+      padding-bottom: 10px ;
+
+      .item {
+        height: 257px;
+        width: 336px;
+        cursor: pointer;
+        border: 1px solid var(--vt-c-border);
+
+        .BG {
+          width: 100%;
+          height: 175px;
+        }
+
+        .infoBox {
+          display: flex;
+          align-items: center;
+          gap: 12px;
+          padding: 0 24px;
+          height: 80px;
+          border-top: none;
+          background: #FFFFFF;
+
+          .avatar {
+            width: 40px;
+            height: 40px;
+            border-radius: 50%;
+          }
+
+          .nameAndType {
+            display: flex;
+            flex-direction: column;
+            gap: 2px;
+
+            .name {
+              font-weight: 700;
+              font-size: 17px;
+              line-height: 22px;
+              color: #010101;
+            }
+
+            .typeBox {
+              display: flex;
+              align-items: center;
+              gap: 10px;
+
+              .type {
+                width: fit-content;
+                //border: 1px solid #b3b3b3;
+                font-weight: 400;
+                font-size: 12px;
+                line-height: 16px;
+                color: #b3b3b3;
+                padding: 0 4px;
+              }
+
+              .type::before {
+                content: "\00B7";
+                margin-right: 5px;
+              }
+            }
+
+          }
+        }
+      }
+
+      //.item:hover {
+      //  box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4);;
+      //}
+    }
+  }
+}
+
+::-webkit-scrollbar {
+  width: 4px; /* 滚动条宽度 */
+}
+
+// /* 滚动条轨道 */
+// ::-webkit-scrollbar-track {
+//   background: #f1f1f1; /* 轨道背景色 */
+// }
+
+/* 滚动条滑块 */
+::-webkit-scrollbar-thumb {
+  background: #888; /* 滑块背景色 */
+}
+
+/* 滚动条滑块悬停状态 */
+::-webkit-scrollbar-thumb:hover {
+  background: #555; /* 悬停状态下滑块背景色 */
+}
+</style>