Total overhaul

This commit is contained in:
Filipe Soccol 2024-11-07 11:35:15 -03:00
parent 9205909f9f
commit 659db5ef04
35 changed files with 1404 additions and 646 deletions

View File

@ -18,12 +18,17 @@
"@headlessui/vue": "^1.7.3", "@headlessui/vue": "^1.7.3",
"@heroicons/vue": "^2.0.12", "@heroicons/vue": "^2.0.12",
"@vueuse/core": "^9.12.0", "@vueuse/core": "^9.12.0",
"@web3-onboard/injected-wallets": "^2.11.2",
"@web3-onboard/vue": "^2.9.0",
"alchemy-sdk": "^2.3.0", "alchemy-sdk": "^2.3.0",
"axios": "^1.2.1", "axios": "^1.2.1",
"crc": "^3.8.0", "crc": "^3.8.0",
"ethers": "^6.13.4",
"marked": "^4.2.12", "marked": "^4.2.12",
"pinia": "^2.0.23", "pinia": "^2.0.23",
"qrcode": "^1.5.1", "qrcode": "^1.5.1",
"viem": "2.x",
"vite-svg-loader": "^5.1.0",
"vue": "^3.2.41", "vue": "^3.2.41",
"vue-markdown": "^2.2.4", "vue-markdown": "^2.2.4",
"vue-router": "^4.1.5" "vue-router": "^4.1.5"
@ -49,7 +54,6 @@
"autoprefixer": "^10.4.12", "autoprefixer": "^10.4.12",
"eslint": "^8.22.0", "eslint": "^8.22.0",
"eslint-plugin-vue": "^9.3.0", "eslint-plugin-vue": "^9.3.0",
"ethers": "^6.13.4",
"jsdom": "^21.1.0", "jsdom": "^21.1.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss": "^8.4.18", "postcss": "^8.4.18",

View File

@ -1,44 +1,45 @@
<script setup lang="ts"> <script setup lang="ts">
import TopBar from "@/components/TopBar/TopBar.vue"; import TopBar from "@/components/TopBar/TopBar.vue";
import SpinnerComponent from "@/components/SpinnerComponent.vue"; import SpinnerComponent from "@/components/SpinnerComponent.vue";
import { init, useOnboard } from "@web3-onboard/vue";
import injectedModule from "@web3-onboard/injected-wallets";
import { Networks } from "./model/Networks";
import { NetworkEnum } from "./model/NetworkEnum";
// import { createAppKit, useAppKit } from "@reown/appkit/vue"; const injected = injectedModule();
// import { EthersAdapter } from "@reown/appkit-adapter-ethers";
// import { sepolia, rootstockTestnet } from "@reown/appkit/networks";
// // 1. Get projectId from https://cloud.reown.com const web3Onboard = init({
// const projectId = "8149aee0a01eeaf7daaf2d326d074b30"; wallets: [injected],
chains: [
{
id: Networks[NetworkEnum.sepolia].chainId,
token: "ETH",
label: "Sepolia",
rpcUrl: import.meta.env.VITE_SEPOLIA_API_URL,
},
{
id: Networks[NetworkEnum.rootstock].chainId,
token: "tRBTC",
label: "Rootstock Testnet",
rpcUrl: import.meta.env.VITE_ROOTSTOCK_API_URL,
},
],
});
// // 2. Create your application's metadata object const { connectedWallet } = useOnboard();
// const metadata = { if (!connectedWallet) {
// name: "p2pix", web3Onboard.connectWallet();
// description: }
// "Uma plataforma descentralizada para transações de criptomoedas ponto-a-ponto usando PIX",
// url: "https://p2pix.doiim.com", // origin must match your domain & subdomain
// icons: ["https://assets.reown.com/reown-profile-pic.png"],
// };
// // 3. Create a AppKit instance
// createAppKit({
// adapters: [new EthersAdapter()],
// networks: [sepolia, rootstockTestnet],
// metadata,
// projectId,
// features: {
// analytics: true, // Optional - defaults to your Cloud configuration
// },
// });
// // 4. Use modal composable
// const modal = useAppKit();
</script> </script>
<template> <template>
<TopBar :modal="modal" /> <TopBar />
<RouterView v-slot="{ Component }"> <RouterView v-slot="{ Component }">
<template v-if="Component"> <template v-if="Component">
<Suspense> <Suspense>
<component :is="Component"></component> <component :is="Component"></component>
<template #fallback> <template #fallback>
<appkit-button />
<div class="flex w-full h-full justify-center items-center"> <div class="flex w-full h-full justify-center items-center">
<SpinnerComponent :width="'16'" :height="'16'"></SpinnerComponent> <SpinnerComponent :width="'16'" :height="'16'"></SpinnerComponent>
</div> </div>

View File

@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.64645 4.64645C1.84171 4.45118 2.15829 4.45118 2.35355 4.64645L8 10.2929L13.6464 4.64645C13.8417 4.45118 14.1583 4.45118 14.3536 4.64645C14.5488 4.84171 14.5488 5.15829 14.3536 5.35355L8.35355 11.3536C8.15829 11.5488 7.84171 11.5488 7.64645 11.3536L1.64645 5.35355C1.45118 5.15829 1.45118 4.84171 1.64645 4.64645Z" fill="white"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M1.64645 4.64645C1.84171 4.45118 2.15829 4.45118 2.35355 4.64645L8 10.2929L13.6464 4.64645C13.8417 4.45118 14.1583 4.45118 14.3536 4.64645C14.5488 4.84171 14.5488 5.15829 14.3536 5.35355L8.35355 11.3536C8.15829 11.5488 7.84171 11.5488 7.64645 11.3536L1.64645 5.35355C1.45118 5.15829 1.45118 4.84171 1.64645 4.64645Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 491 B

View File

@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1.64645 4.64645C1.84171 4.45118 2.15829 4.45118 2.35355 4.64645L8 10.2929L13.6464 4.64645C13.8417 4.45118 14.1583 4.45118 14.3536 4.64645C14.5488 4.84171 14.5488 5.15829 14.3536 5.35355L8.35355 11.3536C8.15829 11.5488 7.84171 11.5488 7.64645 11.3536L1.64645 5.35355C1.45118 5.15829 1.45118 4.84171 1.64645 4.64645Z" fill="black"/>
</svg>

Before

Width:  |  Height:  |  Size: 484 B

View File

@ -1,3 +1,3 @@
<svg width="16" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="16" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.3536 7.35355C13.1583 7.54882 12.8417 7.54882 12.6464 7.35355L7 1.70711L1.35355 7.35355C1.15829 7.54881 0.841709 7.54881 0.646446 7.35355C0.451184 7.15829 0.451184 6.84171 0.646446 6.64645L6.64645 0.646446C6.84171 0.451184 7.15829 0.451184 7.35355 0.646446L13.3536 6.64645C13.5488 6.84171 13.5488 7.15829 13.3536 7.35355Z" fill="#111827"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M13.3536 7.35355C13.1583 7.54882 12.8417 7.54882 12.6464 7.35355L7 1.70711L1.35355 7.35355C1.15829 7.54881 0.841709 7.54881 0.646446 7.35355C0.451184 7.15829 0.451184 6.84171 0.646446 6.64645L6.64645 0.646446C6.84171 0.451184 7.15829 0.451184 7.35355 0.646446L13.3536 6.64645C13.5488 6.84171 13.5488 7.15829 13.3536 7.35355Z" fill="currentColor"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 498 B

View File

@ -1,3 +1,7 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.00016 0.333496C3.31816 0.333496 0.333496 3.32283 0.333496 7.0115C0.333496 9.9615 2.2435 12.4648 4.89283 13.3475C5.22616 13.4088 5.3475 13.2028 5.3475 13.0255C5.3475 12.8675 5.34216 12.4468 5.33883 11.8902C3.48416 12.2935 3.09283 10.9948 3.09283 10.9948C2.79016 10.2228 2.35283 10.0175 2.35283 10.0175C1.7475 9.60416 2.39883 9.61216 2.39883 9.61216C3.0675 9.65883 3.4195 10.3002 3.4195 10.3002C4.01416 11.3202 4.98016 11.0255 5.3595 10.8548C5.42083 10.4235 5.59283 10.1295 5.7835 9.96283C4.3035 9.79416 2.74683 9.22083 2.74683 6.66216C2.74683 5.9335 3.00683 5.33683 3.43283 4.87016C3.36416 4.7015 3.1355 4.02216 3.49816 3.1035C3.49816 3.1035 4.05816 2.9235 5.3315 3.7875C5.87534 3.63917 6.43645 3.56362 7.00016 3.56283C7.56683 3.5655 8.13683 3.6395 8.6695 3.7875C9.94216 2.9235 10.5008 3.10283 10.5008 3.10283C10.8648 4.02216 10.6355 4.7015 10.5675 4.87016C10.9942 5.33683 11.2528 5.9335 11.2528 6.66216C11.2528 9.2275 9.6935 9.79216 8.20883 9.9575C8.44816 10.1635 8.66083 10.5708 8.66083 11.1942C8.66083 12.0862 8.65283 12.8068 8.65283 13.0255C8.65283 13.2042 8.77283 13.4122 9.1115 13.3468C10.439 12.9016 11.5931 12.0504 12.4105 10.9135C13.2279 9.77669 13.6674 8.41171 13.6668 7.0115C13.6668 3.32283 10.6815 0.333496 7.00016 0.333496Z" fill="#1F2937"/> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1.41819,0,0,1.41819,0.0724699,0.290651)">
<path d="M7,0.333C3.318,0.333 0.333,3.323 0.333,7.012C0.333,9.961 2.244,12.465 4.893,13.348C5.226,13.409 5.348,13.203 5.348,13.025C5.348,12.868 5.342,12.447 5.339,11.89C3.484,12.294 3.093,10.995 3.093,10.995C2.79,10.223 2.353,10.018 2.353,10.018C1.748,9.604 2.399,9.612 2.399,9.612C3.068,9.659 3.42,10.3 3.42,10.3C4.014,11.32 4.98,11.025 5.36,10.855C5.421,10.424 5.593,10.13 5.784,9.963C4.304,9.794 2.747,9.221 2.747,6.662C2.747,5.934 3.007,5.337 3.433,4.87C3.364,4.702 3.136,4.022 3.498,3.104C3.498,3.104 4.058,2.924 5.332,3.788C5.875,3.639 6.436,3.564 7,3.563C7.567,3.566 8.137,3.64 8.67,3.788C9.942,2.924 10.501,3.103 10.501,3.103C10.865,4.022 10.636,4.702 10.568,4.87C10.994,5.337 11.253,5.934 11.253,6.662C11.253,9.227 9.694,9.792 8.209,9.958C8.448,10.164 8.661,10.571 8.661,11.194C8.661,12.086 8.653,12.807 8.653,13.025C8.653,13.204 8.773,13.412 9.112,13.347C10.439,12.902 11.593,12.05 12.411,10.914C13.228,9.777 13.667,8.412 13.667,7.012C13.667,3.323 10.682,0.333 7,0.333Z" style="fill:rgb(31,41,55);"/>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +1,7 @@
<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"> <path d="M41,4H9C6.24,4,4,6.24,4,9v32c0,2.76,2.24,5,5,5h32c2.76,0,5-2.24,5-5V9C46,6.24,43.76,4,41,4z M17,20v19h-6V20H17z M11,14.47c0-1.4,1.2-2.47,3-2.47s2.93,1.07,3,2.47c0,1.4-1.12,2.53-3,2.53C12.2,17,11,15.87,11,14.47z M39,39h-6c0,0,0-9.26,0-10 c0-2-1-4-3.5-4.04h-0.08C27,24.96,26,27.02,26,29c0,0.91,0,10,0,10h-6V20h6v2.56c0,0,1.93-2.56,5.81-2.56 c3.97,0,7.19,2.73,7.19,8.26V39z"/></svg> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.426716,0,0,0.426716,-0.646464,-0.646464)">
<path d="M41,4L9,4C6.24,4 4,6.24 4,9L4,41C4,43.76 6.24,46 9,46L41,46C43.76,46 46,43.76 46,41L46,9C46,6.24 43.76,4 41,4ZM17,20L17,39L11,39L11,20L17,20ZM11,14.47C11,13.07 12.2,12 14,12C15.8,12 16.93,13.07 17,14.47C17,15.87 15.88,17 14,17C12.2,17 11,15.87 11,14.47ZM39,39L33,39L33,29C33,27 32,25 29.5,24.96L29.42,24.96C27,24.96 26,27.02 26,29L26,39L20,39L20,20L26,20L26,22.56C26,22.56 27.93,20 31.81,20C35.78,20 39,22.73 39,28.26L39,39Z" style="fill-rule:nonzero;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 1001 B

4
src/assets/sepolia.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16ZM8.16801 2.56435C8.09081 2.43177 7.89923 2.4319 7.82221 2.56458L4.82431 7.72899C4.76983 7.82284 4.80013 7.94301 4.89259 7.99981L7.89038 9.84139C7.95451 9.88079 8.03533 9.88085 8.09952 9.84154L11.1069 7.99986C11.1996 7.94308 11.23 7.82262 11.1752 7.72866L8.16801 2.56435ZM8.08754 10.7831C8.02182 10.8253 7.93759 10.8253 7.87181 10.7833L5.51555 9.27665C5.33379 9.16043 5.1222 9.37463 5.24065 9.55495L7.8123 13.4701C7.89136 13.5905 8.06789 13.5903 8.14678 13.4699L10.7098 9.55566C10.828 9.37517 10.6161 9.16127 10.4345 9.27775L8.08754 10.7831Z" fill="#3B82F6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.82232 2.56456C7.89934 2.43187 8.09092 2.43174 8.16812 2.56432L11.1754 7.72864C11.2301 7.8226 11.1997 7.94305 11.107 7.99984L8.09963 9.84152C8.03544 9.88082 7.95463 9.88077 7.89049 9.84137L4.8927 7.99979C4.80024 7.94299 4.76994 7.82282 4.82442 7.72897L7.82232 2.56456ZM7.87193 10.7833C7.9377 10.8253 8.02193 10.8253 8.08765 10.7831L10.4346 9.27773C10.6162 9.16125 10.8281 9.37515 10.7099 9.55563L8.1469 13.4698C8.06801 13.5903 7.89147 13.5904 7.81241 13.4701L5.24076 9.55492C5.12232 9.3746 5.3339 9.1604 5.51566 9.27662L7.87193 10.7833Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1,3 +1,7 @@
<svg width="14" height="12" viewBox="0 0 14 12" fill="none" xmlns="http://www.w3.org/2000/svg"> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<path d="M4.52683 11.5021C9.55816 11.5021 12.3102 7.33344 12.3102 3.71877C12.3102 3.6001 12.3102 3.4821 12.3022 3.36544C12.8376 2.97779 13.2997 2.49784 13.6668 1.9481C13.1675 2.16944 12.6379 2.31461 12.0955 2.37877C12.6666 2.03681 13.094 1.499 13.2982 0.865436C12.7613 1.18403 12.174 1.40859 11.5615 1.52944C11.1491 1.09061 10.6035 0.799992 10.0092 0.702573C9.41498 0.605153 8.80517 0.706369 8.27424 0.990549C7.74331 1.27473 7.32088 1.72602 7.07236 2.27454C6.82383 2.82307 6.76307 3.43823 6.8995 4.02477C5.81189 3.97026 4.7479 3.68765 3.77659 3.19528C2.80529 2.70291 1.94838 2.01179 1.2615 1.16677C0.911708 1.7689 0.804555 2.48172 0.961853 3.16008C1.11915 3.83844 1.52907 4.43135 2.10816 4.8181C1.673 4.80551 1.24725 4.68844 0.866829 4.47677V4.51144C0.867089 5.14297 1.08576 5.75497 1.48576 6.24367C1.88576 6.73238 2.44247 7.06769 3.0615 7.19277C2.6587 7.30258 2.23609 7.31854 1.82616 7.23944C2.00094 7.78309 2.34128 8.2585 2.79958 8.59918C3.25788 8.93986 3.81121 9.12875 4.38216 9.13944C3.81491 9.58515 3.16535 9.91466 2.47065 10.1091C1.77594 10.3036 1.04971 10.3592 0.333496 10.2728C1.58457 11.0757 3.04029 11.5015 4.52683 11.4994" fill="#1F2937"/> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1.44084,0,0,1.44084,-0.0860978,1.23349)">
<path d="M4.527,11.502C9.558,11.502 12.31,7.333 12.31,3.719C12.31,3.6 12.31,3.482 12.302,3.365C12.838,2.978 13.3,2.498 13.667,1.948C13.168,2.169 12.638,2.315 12.096,2.379C12.667,2.037 13.094,1.499 13.298,0.865C12.761,1.184 12.174,1.409 11.562,1.529C11.149,1.091 10.604,0.8 10.009,0.703C9.415,0.605 8.805,0.706 8.274,0.991C7.743,1.275 7.321,1.726 7.072,2.275C6.824,2.823 6.763,3.438 6.9,4.025C5.812,3.97 4.748,3.688 3.777,3.195C2.805,2.703 1.948,2.012 1.262,1.167C0.912,1.769 0.805,2.482 0.962,3.16C1.119,3.838 1.529,4.431 2.108,4.818C1.673,4.806 1.247,4.688 0.867,4.477L0.867,4.511C0.867,5.143 1.086,5.755 1.486,6.244C1.886,6.732 2.442,7.068 3.062,7.193C2.659,7.303 2.236,7.319 1.826,7.239C2.001,7.783 2.341,8.259 2.8,8.599C3.258,8.94 3.811,9.129 4.382,9.139C3.815,9.585 3.165,9.915 2.471,10.109C1.776,10.304 1.05,10.359 0.333,10.273C1.585,11.076 3.04,11.502 4.527,11.499" style="fill:rgb(31,41,55);fill-rule:nonzero;"/>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -26,7 +26,7 @@ describe("addresses.ts functions", () => {
it("getTokenAddress Ethereum", () => { it("getTokenAddress Ethereum", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.ethereum); etherStore.setNetworkId(NetworkEnum.sepolia);
expect(getTokenAddress(TokenEnum.BRZ)).toBe( expect(getTokenAddress(TokenEnum.BRZ)).toBe(
"0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00" "0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00"
); );
@ -34,7 +34,7 @@ describe("addresses.ts functions", () => {
it("getTokenAddress Polygon", () => { it("getTokenAddress Polygon", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.polygon); etherStore.setNetworkId(NetworkEnum.polygon);
expect(getTokenAddress(TokenEnum.BRZ)).toBe( expect(getTokenAddress(TokenEnum.BRZ)).toBe(
"0xC86042E9F2977C62Da8c9dDF7F9c40fde4796A29" "0xC86042E9F2977C62Da8c9dDF7F9c40fde4796A29"
); );
@ -42,7 +42,7 @@ describe("addresses.ts functions", () => {
it("getTokenAddress Rootstock", () => { it("getTokenAddress Rootstock", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.rootstock); etherStore.setNetworkId(NetworkEnum.rootstock);
expect(getTokenAddress(TokenEnum.BRZ)).toBe( expect(getTokenAddress(TokenEnum.BRZ)).toBe(
"0xfE841c74250e57640390f46d914C88d22C51e82e" "0xfE841c74250e57640390f46d914C88d22C51e82e"
); );
@ -57,7 +57,7 @@ describe("addresses.ts functions", () => {
it("getP2PixAddress Ethereum", () => { it("getP2PixAddress Ethereum", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.ethereum); etherStore.setNetworkId(NetworkEnum.sepolia);
expect(getP2PixAddress()).toBe( expect(getP2PixAddress()).toBe(
"0x2414817FF64A114d91eCFA16a834d3fCf69103d4" "0x2414817FF64A114d91eCFA16a834d3fCf69103d4"
); );
@ -65,7 +65,7 @@ describe("addresses.ts functions", () => {
it("getP2PixAddress Polygon", () => { it("getP2PixAddress Polygon", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.polygon); etherStore.setNetworkId(NetworkEnum.polygon);
expect(getP2PixAddress()).toBe( expect(getP2PixAddress()).toBe(
"0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00" "0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00"
); );
@ -73,7 +73,7 @@ describe("addresses.ts functions", () => {
it("getP2PixAddress Rootstock", () => { it("getP2PixAddress Rootstock", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.rootstock); etherStore.setNetworkId(NetworkEnum.rootstock);
expect(getP2PixAddress()).toBe( expect(getP2PixAddress()).toBe(
"0x98ba35eb14b38D6Aa709338283af3e922476dE34" "0x98ba35eb14b38D6Aa709338283af3e922476dE34"
); );
@ -87,19 +87,19 @@ describe("addresses.ts functions", () => {
it("getProviderUrl Ethereum", () => { it("getProviderUrl Ethereum", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.ethereum); etherStore.setNetworkId(NetworkEnum.sepolia);
expect(getProviderUrl()).toBe(import.meta.env.VITE_GOERLI_API_URL); expect(getProviderUrl()).toBe(import.meta.env.VITE_GOERLI_API_URL);
}); });
it("getProviderUrl Polygon", () => { it("getProviderUrl Polygon", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.polygon); etherStore.setNetworkId(NetworkEnum.polygon);
expect(getProviderUrl()).toBe(import.meta.env.VITE_MUMBAI_API_URL); expect(getProviderUrl()).toBe(import.meta.env.VITE_MUMBAI_API_URL);
}); });
it("getProviderUrl Rootstock", () => { it("getProviderUrl Rootstock", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.rootstock); etherStore.setNetworkId(NetworkEnum.rootstock);
expect(getProviderUrl()).toBe(import.meta.env.VITE_ROOTSTOCK_API_URL); expect(getProviderUrl()).toBe(import.meta.env.VITE_ROOTSTOCK_API_URL);
}); });
@ -109,7 +109,7 @@ describe("addresses.ts functions", () => {
it("isPossibleNetwork Returns", () => { it("isPossibleNetwork Returns", () => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
etherStore.setNetworkName(NetworkEnum.ethereum); etherStore.setNetworkId(NetworkEnum.sepolia);
expect(isPossibleNetwork(0x5)).toBe(true); expect(isPossibleNetwork(0x5)).toBe(true);
expect(isPossibleNetwork(5)).toBe(true); expect(isPossibleNetwork(5)).toBe(true);
expect(isPossibleNetwork(0x13881)).toBe(true); expect(isPossibleNetwork(0x13881)).toBe(true);

View File

@ -1,8 +1,8 @@
import { useEtherStore } from "@/store/ether"; import { useEtherStore } from "@/store/ether";
import { NetworkEnum, TokenEnum } from "@/model/NetworkEnum"; import { NetworkEnum, TokenEnum } from "@/model/NetworkEnum";
const Tokens: { [key in NetworkEnum]: {[key in TokenEnum] :string} } = { const Tokens: { [key in NetworkEnum]: { [key in TokenEnum]: string } } = {
[NetworkEnum.ethereum]: { [NetworkEnum.sepolia]: {
BRZ: "0x3eBE67A2C7bdB2081CBd34ba3281E90377462289", BRZ: "0x3eBE67A2C7bdB2081CBd34ba3281E90377462289",
BRX: "0x3eBE67A2C7bdB2081CBd34ba3281E90377462289", BRX: "0x3eBE67A2C7bdB2081CBd34ba3281E90377462289",
}, },
@ -17,7 +17,7 @@ const Tokens: { [key in NetworkEnum]: {[key in TokenEnum] :string} } = {
}; };
export const getTokenByAddress = (address: string) => { export const getTokenByAddress = (address: string) => {
for ( const [, network] of Object.entries(NetworkEnum) ) { for (const [, network] of Object.entries(NetworkEnum)) {
for (const token of Object.keys(Tokens[network as NetworkEnum])) { for (const token of Object.keys(Tokens[network as NetworkEnum])) {
if (address === Tokens[network as NetworkEnum][token as TokenEnum]) { if (address === Tokens[network as NetworkEnum][token as TokenEnum]) {
return token as TokenEnum; return token as TokenEnum;
@ -36,7 +36,7 @@ const getTokenAddress = (token: TokenEnum, network?: NetworkEnum): string => {
const getP2PixAddress = (network?: NetworkEnum): string => { const getP2PixAddress = (network?: NetworkEnum): string => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
const possibleP2PixAddresses: { [key in NetworkEnum]: string } = { const possibleP2PixAddresses: { [key in NetworkEnum]: string } = {
[NetworkEnum.ethereum]: "0xb7cD135F5eFD9760981e02E2a898790b688939fe", [NetworkEnum.sepolia]: "0xb7cD135F5eFD9760981e02E2a898790b688939fe",
[NetworkEnum.polygon]: "0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00", [NetworkEnum.polygon]: "0x4A2886EAEc931e04297ed336Cc55c4eb7C75BA00",
[NetworkEnum.rootstock]: "0x98ba35eb14b38D6Aa709338283af3e922476dE34", [NetworkEnum.rootstock]: "0x98ba35eb14b38D6Aa709338283af3e922476dE34",
}; };
@ -47,7 +47,7 @@ const getP2PixAddress = (network?: NetworkEnum): string => {
const getProviderUrl = (): string => { const getProviderUrl = (): string => {
const etherStore = useEtherStore(); const etherStore = useEtherStore();
const possibleProvidersUrls: { [key in NetworkEnum]: string } = { const possibleProvidersUrls: { [key in NetworkEnum]: string } = {
[NetworkEnum.ethereum]: import.meta.env.VITE_SEPOLIA_API_URL, [NetworkEnum.sepolia]: import.meta.env.VITE_SEPOLIA_API_URL,
[NetworkEnum.polygon]: import.meta.env.VITE_MUMBAI_API_URL, [NetworkEnum.polygon]: import.meta.env.VITE_MUMBAI_API_URL,
[NetworkEnum.rootstock]: import.meta.env.VITE_RSK_API_URL, [NetworkEnum.rootstock]: import.meta.env.VITE_RSK_API_URL,
}; };

View File

@ -21,7 +21,7 @@ const getNetworksLiquidity = async (): Promise<void> => {
); // rootstock provider ); // rootstock provider
const p2pContractSepolia = new Contract( const p2pContractSepolia = new Contract(
getP2PixAddress(NetworkEnum.ethereum), getP2PixAddress(NetworkEnum.sepolia),
p2pix.abi, p2pix.abi,
sepoliaProvider sepoliaProvider
); );
@ -34,7 +34,7 @@ const getNetworksLiquidity = async (): Promise<void> => {
etherStore.setLoadingNetworkLiquidity(true); etherStore.setLoadingNetworkLiquidity(true);
const depositListSepolia = await getValidDeposits( const depositListSepolia = await getValidDeposits(
getTokenAddress(etherStore.selectedToken, NetworkEnum.ethereum), getTokenAddress(etherStore.selectedToken, NetworkEnum.sepolia),
p2pContractSepolia p2pContractSepolia
); );
// const depositListMumbai = await getValidDeposits( // const depositListMumbai = await getValidDeposits(

View File

@ -1,96 +1,27 @@
import { useEtherStore } from "@/store/ether";
import p2pix from "@/utils/smart_contract_files/P2PIX.json"; import p2pix from "@/utils/smart_contract_files/P2PIX.json";
import { updateWalletStatus } from "./wallet"; import { updateWalletStatus } from "./wallet";
import { import { getProviderUrl, getP2PixAddress } from "./addresses";
getProviderUrl,
isPossibleNetwork,
getP2PixAddress,
} from "./addresses";
import type { NetworkEnum } from "@/model/NetworkEnum";
import { Networks } from "@/model/Networks";
import { BrowserProvider, JsonRpcProvider, Contract } from "ethers"; import { BrowserProvider, JsonRpcProvider, Contract } from "ethers";
const getProvider = ( let provider: BrowserProvider | JsonRpcProvider | null = null;
onlyAlchemyProvider: boolean = false
): BrowserProvider | JsonRpcProvider => { const getProvider = (onlyAlchemyProvider: boolean = false) => {
if (onlyAlchemyProvider) return new JsonRpcProvider(getProviderUrl()); // alchemy provider if (onlyAlchemyProvider) return new JsonRpcProvider(getProviderUrl()); // alchemy provider
return (window as any).ethereum as BrowserProvider; return provider;
}; };
const getContract = async (onlyAlchemyProvider: boolean = false) => { const getContract = async (onlyAlchemyProvider: boolean = false) => {
const provider = getProvider(onlyAlchemyProvider); const p = getProvider(onlyAlchemyProvider);
const signer = await provider.getSigner();
return new Contract(getP2PixAddress(), p2pix.abi, signer);
};
const connectProvider = async (): Promise<void> => {
const window_ = window as any;
const connection = window_.ethereum;
const provider = getProvider();
await (provider as any).enable();
if (!(provider instanceof BrowserProvider)) {
window.alert("Please, connect to metamask extension");
return;
}
await updateWalletStatus();
listenToNetworkChange(connection);
listenToWalletChange(connection);
};
const listenToWalletChange = (connection: any): void => {
connection.on("accountsChanged", async () => {
console.log("Changed account!");
updateWalletStatus();
});
};
const listenToNetworkChange = (connection: any) => {
const etherStore = useEtherStore();
connection.on("chainChanged", (networkChain: NetworkEnum) => {
console.log("Changed network!");
if (isPossibleNetwork(networkChain)) {
etherStore.setNetworkName(networkChain);
updateWalletStatus();
} else {
window.alert("Invalid chain!");
}
});
};
const requestNetworkChange = async (network: NetworkEnum): Promise<boolean> => {
const etherStore = useEtherStore();
if (!etherStore.walletAddress) return true;
const window_ = window as any;
try { try {
await window_.ethereum.request({ const signer = await p?.getSigner();
method: "wallet_switchEthereumChain", return new Contract(getP2PixAddress(), p2pix.abi, signer);
params: [{ chainId: Networks[network].chainId }], // chainId must be in hexadecimal numbers } catch (err) {
}); return new Contract(getP2PixAddress(), p2pix.abi, p);
} catch (e: any) {
if (e.code == 4902) {
// Unrecognized chain ID
await window_.ethereum.request({
method: "wallet_addEthereumChain",
params: [Networks[network]],
});
}
} }
return true;
}; };
export { const connectProvider = async (p: any): Promise<void> => {
getProvider, provider = new BrowserProvider(p, "any");
getContract, await updateWalletStatus();
connectProvider,
listenToNetworkChange,
requestNetworkChange,
}; };
export { getProvider, getContract, connectProvider };

View File

@ -8,7 +8,7 @@ import { useEtherStore } from "@/store/ether";
const approveTokens = async (tokenQty: string): Promise<any> => { const approveTokens = async (tokenQty: string): Promise<any> => {
const provider = getProvider(); const provider = getProvider();
const signer = await provider.getSigner(); const signer = await provider?.getSigner();
const etherStore = useEtherStore(); const etherStore = useEtherStore();
const tokenContract = new Contract( const tokenContract = new Contract(
@ -17,13 +17,21 @@ const approveTokens = async (tokenQty: string): Promise<any> => {
signer signer
); );
const apprv = await tokenContract.approve( // Check if the token is already approved
getP2PixAddress(), const approved = await tokenContract.allowance(
parseEther(tokenQty) await signer?.getAddress(),
getP2PixAddress()
); );
if (approved < parseEther(tokenQty)) {
await apprv.wait(); // Approve tokens
return apprv; const apprv = await tokenContract.approve(
getP2PixAddress(),
parseEther(tokenQty)
);
await apprv.wait();
return true;
}
return true;
}; };
const addDeposit = async (tokenQty: string, pixKey: string): Promise<any> => { const addDeposit = async (tokenQty: string, pixKey: string): Promise<any> => {

View File

@ -32,7 +32,7 @@ export const updateWalletStatus = async (): Promise<void> => {
window.alert("Invalid chain!:" + chainId); window.alert("Invalid chain!:" + chainId);
return; return;
} }
etherStore.setNetworkName(Number(chainId)); etherStore.setNetworkId(Number(chainId));
const mockTokenContract = new Contract( const mockTokenContract = new Contract(
getTokenAddress(etherStore.selectedToken), getTokenAddress(etherStore.selectedToken),

View File

@ -146,7 +146,7 @@ p {
@apply text-white text-center; @apply text-white text-center;
} }
.blur-container-row { .blur-container-row {
@apply flex flex-row justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 w-1/3; @apply flex flex-row justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 max-w-screen-sm;
} }
.blur-container { .blur-container {
@ -165,22 +165,4 @@ input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none; -webkit-appearance: none;
} }
.lg-view {
display: inline-block;
}
.sm-view {
display: none;
}
@media screen and (max-width: 500px) {
.lg-view {
display: none;
}
.sm-view {
display: inline-block;
}
}
</style> </style>

View File

@ -38,9 +38,9 @@ switch (props.type) {
<div <div
class="modal-overlay sm:h-12 h-full inset-0 absolute backdrop-blur-sm sm:backdrop-blur-none" class="modal-overlay sm:h-12 h-full inset-0 absolute backdrop-blur-sm sm:backdrop-blur-none"
> >
<div class="modal px-12 pl-72 text-center sm:flex justify-between hidden"> <div class="modal px-12 text-center sm:flex justify-between hidden">
<div class="flex items-center"> <div class="flex items-center">
<p class="text-black tracking-tighter leading-tight my-2"> <p class="text-black tracking-tighter leading-tight py-2">
{{ alertText }} {{ alertText }}
</p> </p>
<button v-if="props.type === 'redirect'" @click="$emit('go-to-lock')"> <button v-if="props.type === 'redirect'" @click="$emit('go-to-lock')">
@ -110,7 +110,6 @@ switch (props.type) {
border-radius: 10px; border-radius: 10px;
align-items: center; align-items: center;
white-space: nowrap; white-space: nowrap;
padding-left: v-bind(alertPaddingLeft);
} }
.modal-mobile { .modal-mobile {

View File

@ -96,7 +96,7 @@ const getRemaining = (): number => {
}; };
const getExplorer = (): string => { const getExplorer = (): string => {
return etherStore.networkName == NetworkEnum.ethereum return etherStore.networkName == NetworkEnum.sepolia
? "Etherscan" ? "Etherscan"
: "Polygonscan"; : "Polygonscan";
}; };
@ -107,7 +107,7 @@ const showInitialItems = (): void => {
const openEtherscanUrl = (transactionHash: string): void => { const openEtherscanUrl = (transactionHash: string): void => {
const networkUrl = const networkUrl =
etherStore.networkName == NetworkEnum.ethereum etherStore.networkName == NetworkEnum.sepolia
? "sepolia.etherscan.io" ? "sepolia.etherscan.io"
: "mumbai.polygonscan.com"; : "mumbai.polygonscan.com";
const url = `https://${networkUrl}/tx/${transactionHash}`; const url = `https://${networkUrl}/tx/${transactionHash}`;
@ -190,7 +190,7 @@ showInitialItems();
> >
<img <img
alt="info image" alt="info image"
src="@/assets/info.svg" src="@/assets/info.svg?url"
aria-describedby="tooltip" aria-describedby="tooltip"
ref="reference" ref="reference"
@mouseover="showInfoTooltip = true" @mouseover="showInfoTooltip = true"
@ -216,7 +216,7 @@ showInitialItems();
> >
<img <img
alt="Withdraw image" alt="Withdraw image"
src="@/assets/withdraw.svg" src="@/assets/withdraw.svg?url"
class="w-3 h-3 sm:w-4 sm:h-4" class="w-3 h-3 sm:w-4 sm:h-4"
/> />
<span class="last-release-info">Sacar</span> <span class="last-release-info">Sacar</span>
@ -263,7 +263,7 @@ showInitialItems();
> >
<img <img
alt="Withdraw image" alt="Withdraw image"
src="@/assets/withdraw.svg" src="@/assets/withdraw.svg?url"
class="w-3 h-3 sm:w-4 sm:h-4" class="w-3 h-3 sm:w-4 sm:h-4"
/> />
<span class="last-release-info">Sacar</span> <span class="last-release-info">Sacar</span>
@ -318,7 +318,7 @@ showInitialItems();
<span class="last-release-info">{{ getExplorer() }}</span> <span class="last-release-info">{{ getExplorer() }}</span>
<img <img
alt="Redirect image" alt="Redirect image"
src="@/assets/redirect.svg" src="@/assets/redirect.svg?url"
class="w-3 h-3 sm:w-4 sm:h-4" class="w-3 h-3 sm:w-4 sm:h-4"
/> />
</div> </div>

View File

@ -24,7 +24,7 @@ const props = defineProps({
> >
<img <img
alt="Polygon image" alt="Polygon image"
src="@/assets/validating.svg" src="@/assets/validating.svg?url"
width="96" width="96"
height="48" height="48"
/> />

View File

@ -110,12 +110,12 @@ onUnmounted(() => {
</div> </div>
<img <img
alt="Copy PIX code" alt="Copy PIX code"
src="@/assets/copyPix.svg" src="@/assets/copyPix.svg?url"
width="16" width="16"
height="16" height="16"
class="pt-2 lg:mb-5 cursor-pointer" class="pt-2 lg:mb-5 cursor-pointer"
/> />
<span class="text-xs text-start lg-view"> <span class="text-xs text-start hidden md:inline-block">
<strong>ATENÇÃO!</strong> A transação será processada após inserir <strong>ATENÇÃO!</strong> A transação será processada após inserir
o código de autenticação. Caso contrário não conseguiremos comprovar o o código de autenticação. Caso contrário não conseguiremos comprovar o
seu depósito e não será possível transferir os tokens para sua seu depósito e não será possível transferir os tokens para sua
@ -139,7 +139,7 @@ onUnmounted(() => {
<div class="flex items-center h-8"> <div class="flex items-center h-8">
<img <img
alt="Invalid Icon" alt="Invalid Icon"
src="@/assets/invalidIcon.svg" src="@/assets/invalidIcon.svg?url"
width="14" width="14"
class="cursor-pointer align-middle inline-block" class="cursor-pointer align-middle inline-block"
/> />
@ -152,7 +152,7 @@ onUnmounted(() => {
<div class="flex items-center h-8"> <div class="flex items-center h-8">
<img <img
alt="Valid Icon" alt="Valid Icon"
src="@/assets/validIcon.svg" src="@/assets/validIcon.svg?url"
width="14" width="14"
class="cursor-pointer align-middle inline-block" class="cursor-pointer align-middle inline-block"
/> />
@ -222,7 +222,7 @@ h2 {
} }
.blur-container { .blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-6; @apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-6 max-w-screen-sm;
} }
input[type="number"] { input[type="number"] {
@ -233,22 +233,4 @@ input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none; -webkit-appearance: none;
} }
.lg-view {
display: inline-block;
}
.sm-view {
display: none;
}
@media screen and (max-width: 500px) {
.lg-view {
display: none;
}
.sm-view {
display: inline-block;
}
}
</style> </style>

View File

@ -4,7 +4,6 @@ import CustomButton from "@/components/CustomButton/CustomButton.vue";
import { debounce } from "@/utils/debounce"; import { debounce } from "@/utils/debounce";
import { useEtherStore } from "@/store/ether"; import { useEtherStore } from "@/store/ether";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { connectProvider } from "@/blockchain/provider";
import { verifyNetworkLiquidity } from "@/utils/networkLiquidity"; import { verifyNetworkLiquidity } from "@/utils/networkLiquidity";
import { NetworkEnum } from "@/model/NetworkEnum"; import { NetworkEnum } from "@/model/NetworkEnum";
import type { ValidDeposit } from "@/model/ValidDeposit"; import type { ValidDeposit } from "@/model/ValidDeposit";
@ -38,24 +37,25 @@ const enableWalletButton = ref<boolean>(false);
const hasLiquidity = ref<boolean>(true); const hasLiquidity = ref<boolean>(true);
const validDecimals = ref<boolean>(true); const validDecimals = ref<boolean>(true);
const selectedSepoliaDeposit = ref<ValidDeposit>(); const selectedSepoliaDeposit = ref<ValidDeposit>();
const selectedMumbaiDeposit = ref<ValidDeposit>();
const selectedRootstockDeposit = ref<ValidDeposit>(); const selectedRootstockDeposit = ref<ValidDeposit>();
import ChevronDown from "@/assets/chevronDown.svg";
import { useOnboard } from "@web3-onboard/vue";
// Emits // Emits
const emit = defineEmits(["tokenBuy"]); const emit = defineEmits(["tokenBuy"]);
// Blockchain methods // Blockchain methods
const connectAccount = async (): Promise<void> => { const connectAccount = async (): Promise<void> => {
await connectProvider(); const { connectWallet } = useOnboard();
await connectWallet();
enableOrDisableConfirmButton();
}; };
const emitConfirmButton = (): void => { const emitConfirmButton = (): void => {
const selectedDeposit = const selectedDeposit =
networkName.value == NetworkEnum.ethereum networkName.value == NetworkEnum.sepolia
? selectedSepoliaDeposit.value ? selectedSepoliaDeposit.value
: selectedMumbaiDeposit.value; : selectedRootstockDeposit.value;
emit("tokenBuy", selectedDeposit, tokenValue.value); emit("tokenBuy", selectedDeposit, tokenValue.value);
}; };
@ -92,7 +92,7 @@ const handleSelectedToken = (token: TokenEnum): void => {
const verifyLiquidity = (): void => { const verifyLiquidity = (): void => {
enableConfirmButton.value = false; enableConfirmButton.value = false;
selectedSepoliaDeposit.value = undefined; selectedSepoliaDeposit.value = undefined;
selectedMumbaiDeposit.value = undefined; selectedRootstockDeposit.value = undefined;
selectedRootstockDeposit.value = undefined; selectedRootstockDeposit.value = undefined;
if (tokenValue.value <= 0) { if (tokenValue.value <= 0) {
@ -105,14 +105,14 @@ const verifyLiquidity = (): void => {
walletAddress.value, walletAddress.value,
depositsValidListSepolia.value depositsValidListSepolia.value
); );
selectedMumbaiDeposit.value = verifyNetworkLiquidity( selectedRootstockDeposit.value = verifyNetworkLiquidity(
tokenValue.value, tokenValue.value,
walletAddress.value, walletAddress.value,
depositsValidListMumbai.value depositsValidListMumbai.value
); );
enableOrDisableConfirmButton(); enableOrDisableConfirmButton();
if (selectedSepoliaDeposit.value || selectedMumbaiDeposit.value) { if (selectedSepoliaDeposit.value || selectedRootstockDeposit.value) {
hasLiquidity.value = true; hasLiquidity.value = true;
enableWalletButton.value = true; enableWalletButton.value = true;
} else { } else {
@ -122,10 +122,10 @@ const verifyLiquidity = (): void => {
}; };
const enableOrDisableConfirmButton = (): void => { const enableOrDisableConfirmButton = (): void => {
if (selectedSepoliaDeposit.value && networkName.value == NetworkEnum.ethereum) if (selectedSepoliaDeposit.value && networkName.value == NetworkEnum.sepolia)
enableConfirmButton.value = true; enableConfirmButton.value = true;
else if ( else if (
selectedMumbaiDeposit.value && selectedRootstockDeposit.value &&
networkName.value == NetworkEnum.polygon networkName.value == NetworkEnum.polygon
) )
enableConfirmButton.value = true; enableConfirmButton.value = true;
@ -183,21 +183,24 @@ watch(walletAddress, (): void => {
class="sm:w-fit w-4" class="sm:w-fit w-4"
:src="getTokenImage(selectedToken)" :src="getTokenImage(selectedToken)"
/> />
<span class="text-gray-900 sm:text-lg text-md font-medium" id="token">{{ <span
selectedToken class="text-gray-900 sm:text-lg text-md font-medium"
}}</span> id="token"
<img >{{ selectedToken }}</span
class="text-gray-900 pr-4 sm:pr-0 transition-all duration-500 ease-in-out" >
:class="{'scale-y-[-1]': selectTokenToggle}" <ChevronDown
class="pr-4 sm:pr-0 transition-all duration-500 ease-in-out invert"
:class="{ 'scale-y-[-1]': selectTokenToggle }"
alt="Chevron Down" alt="Chevron Down"
src="@/assets/chevronDownBlack.svg"
/> />
</button> </button>
<div <div
v-if="selectTokenToggle" v-if="selectTokenToggle"
class="mt-2 w-[100px] text-gray-900 absolute" class="mt-2 w-[100px] text-gray-900 absolute"
> >
<div class="bg-white rounded-xl z-10 border border-gray-300 drop-shadow-md shadow-md overflow-clip"> <div
class="bg-white rounded-xl z-10 border border-gray-300 drop-shadow-md shadow-md overflow-clip"
>
<div <div
v-for="token in TokenEnum" v-for="token in TokenEnum"
class="flex menu-button gap-2 px-4 cursor-pointer hover:bg-gray-300 transition-colors" class="flex menu-button gap-2 px-4 cursor-pointer hover:bg-gray-300 transition-colors"
@ -233,10 +236,10 @@ watch(walletAddress, (): void => {
<div class="flex gap-2"> <div class="flex gap-2">
<img <img
alt="Polygon image" alt="Polygon image"
src="@/assets/polygon.svg" src="@/assets/polygon.svg?svg"
width="24" width="24"
height="24" height="24"
v-if="selectedMumbaiDeposit" v-if="selectedRootstockDeposit"
/> />
<img <img
alt="Ethereum image" alt="Ethereum image"
@ -313,7 +316,7 @@ watch(walletAddress, (): void => {
} }
.blur-container { .blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 mt-10; @apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 mt-10 max-w-screen-sm;
} }
input[type="number"] { input[type="number"] {

View File

@ -4,12 +4,14 @@ import CustomButton from "@/components/CustomButton/CustomButton.vue";
import { debounce } from "@/utils/debounce"; import { debounce } from "@/utils/debounce";
import { decimalCount } from "@/utils/decimalCount"; import { decimalCount } from "@/utils/decimalCount";
import { TokenEnum } from "@/model/NetworkEnum";
import { useEtherStore } from "@/store/ether"; import { useEtherStore } from "@/store/ether";
import { getTokenImage } from "@/utils/imagesPath"; import { getTokenImage } from "@/utils/imagesPath";
import { storeToRefs } from "pinia";
import { useOnboard } from "@web3-onboard/vue";
// Store // Store
const etherStore = useEtherStore(); const etherStore = useEtherStore();
const { walletAddress } = storeToRefs(etherStore);
// Reactive state // Reactive state
const tokenValue = ref<number>(0); const tokenValue = ref<number>(0);
@ -20,6 +22,12 @@ const validDecimals = ref<boolean>(true);
// Emits // Emits
const emit = defineEmits(["tokenBuy"]); const emit = defineEmits(["tokenBuy"]);
// Blockchain methods
const connectAccount = async (): Promise<void> => {
const { connectWallet } = useOnboard();
await connectWallet();
};
// Debounce methods // Debounce methods
const handleInputEvent = (event: any): void => { const handleInputEvent = (event: any): void => {
const { value } = event.target; const { value } = event.target;
@ -84,13 +92,13 @@ const handleInputEvent = (event: any): void => {
<div class="flex gap-2"> <div class="flex gap-2">
<img <img
alt="Polygon image" alt="Polygon image"
src="@/assets/polygon.svg" src="@/assets/polygon.svg?url"
width="24" width="24"
height="24" height="24"
/> />
<img <img
alt="Ethereum image" alt="Ethereum image"
src="@/assets/ethereum.svg" src="@/assets/ethereum.svg?url"
width="24" width="24"
height="24" height="24"
/> />
@ -109,9 +117,15 @@ const handleInputEvent = (event: any): void => {
</div> </div>
<CustomButton <CustomButton
v-if="walletAddress"
:text="'Conectar carteira'" :text="'Conectar carteira'"
@buttonClicked="emit('tokenBuy')" @buttonClicked="emit('tokenBuy')"
/> />
<CustomButton
v-if="!walletAddress"
:text="'Conectar carteira'"
@buttonClicked="connectAccount()"
/>
</div> </div>
</div> </div>
</template> </template>

View File

@ -76,7 +76,7 @@ p {
} }
.blur-container { .blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 sm:w-1/3; @apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 max-w-screen-sm;
} }
.last-deposit-info { .last-deposit-info {

View File

@ -10,6 +10,7 @@ import { connectProvider } from "@/blockchain/provider";
import { TokenEnum } from "@/model/NetworkEnum"; import { TokenEnum } from "@/model/NetworkEnum";
import { getTokenImage } from "@/utils/imagesPath"; import { getTokenImage } from "@/utils/imagesPath";
import { onClickOutside } from "@vueuse/core"; import { onClickOutside } from "@vueuse/core";
import { useOnboard } from "@web3-onboard/vue";
// html references // html references
const tokenDropdownRef = ref<any>(null); const tokenDropdownRef = ref<any>(null);
@ -30,6 +31,12 @@ const validPixFormat = ref<boolean>(true);
// Emits // Emits
const emit = defineEmits(["approveTokens"]); const emit = defineEmits(["approveTokens"]);
// Blockchain methods
const connectAccount = async (): Promise<void> => {
const { connectWallet } = useOnboard();
await connectWallet();
};
// Debounce methods // Debounce methods
const handleInputEvent = (event: any): void => { const handleInputEvent = (event: any): void => {
const { value } = event.target; const { value } = event.target;
@ -72,14 +79,12 @@ const handleSelectedToken = (token: TokenEnum): void => {
selectTokenToggle.value = false; selectTokenToggle.value = false;
}; };
const handleButtonClick = async ( const handleSellClick = async (
offer: string, offer: string,
pixKey: string pixKey: string
): Promise<void> => { ): Promise<void> => {
const postProcessedPixKey = postProcessKey(pixKey); const postProcessedPixKey = postProcessKey(pixKey);
if (walletAddress.value) emit("approveTokens", { offer, postProcessedPixKey });
emit("approveTokens", { offer, postProcessedPixKey });
else await connectProvider();
}; };
</script> </script>
@ -130,11 +135,10 @@ const handleButtonClick = async (
id="token" id="token"
>{{ selectedToken }}</span >{{ selectedToken }}</span
> >
<img <ChevronDown
class="text-gray-900 pr-4 sm:pr-0 transition-all duration-500 ease-in-out" class="pr-4 sm:pr-0 transition-all duration-500 ease-in-out invert"
:class="{ 'scale-y-[-1]': selectTokenToggle }" :class="{ 'scale-y-[-1]': selectTokenToggle }"
alt="Chevron Down" alt="Chevron Down"
src="@/assets/chevronDownBlack.svg"
/> />
</button> </button>
<div <div
@ -200,9 +204,15 @@ const handleButtonClick = async (
</div> </div>
</div> </div>
<CustomButton <CustomButton
:text="walletAddress ? 'Aprovar tokens' : 'Conectar Carteira'" v-if="walletAddress"
:text="'Aprovar tokens'"
:isDisabled="!validDecimals || !validPixFormat" :isDisabled="!validDecimals || !validPixFormat"
@buttonClicked="handleButtonClick(offer, pixKey)" @buttonClicked="handleSellClick(offer, pixKey)"
/>
<CustomButton
v-if="!walletAddress"
:text="'Conectar carteira'"
@buttonClicked="connectAccount()"
/> />
</div> </div>
</div> </div>
@ -232,7 +242,7 @@ const handleButtonClick = async (
} }
.blur-container { .blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 mt-10 w-auto; @apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 mt-10 max-w-screen-sm;
} }
input[type="number"] { input[type="number"] {

View File

@ -1,33 +1,51 @@
<script setup lang="ts"> <script setup lang="ts">
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
import { useEtherStore } from "@/store/ether"; import { useEtherStore } from "@/store/ether";
import { ref } from "vue"; import { ref, watch } from "vue";
import { onClickOutside } from "@vueuse/core"; import { onClickOutside } from "@vueuse/core";
import { NetworkEnum } from "@/model/NetworkEnum"; import { NetworkEnum } from "@/model/NetworkEnum";
import { connectProvider, requestNetworkChange } from "@/blockchain/provider";
import { getNetworkImage } from "@/utils/imagesPath"; import { getNetworkImage } from "@/utils/imagesPath";
import { Networks } from "@/model/Networks"; import { Networks } from "@/model/Networks";
import { useOnboard } from "@web3-onboard/vue";
import ChevronDown from "@/assets/chevronDown.svg";
import Account from "@/assets/account.svg";
import TwitterIcon from "@/assets/twitterIcon.svg";
import LinkedinIcon from "@/assets/linkedinIcon.svg";
import GithubIcon from "@/assets/githubIcon.svg";
import { connectProvider } from "@/blockchain/provider";
// Store reference // Store reference
const etherStore = useEtherStore(); const etherStore = useEtherStore();
const { walletAddress, sellerView } = storeToRefs(etherStore); const { walletAddress, sellerView } = storeToRefs(etherStore);
const menuOpenToggle = ref<boolean>(false); const menuOpenToggle = ref<boolean>(false);
const menuHoverToggle = ref<boolean>(false);
const infoMenuOpenToggle = ref<boolean>(false); const infoMenuOpenToggle = ref<boolean>(false);
const currencyMenuOpenToggle = ref<boolean>(false); const currencyMenuOpenToggle = ref<boolean>(false);
const currencyMenuHoverToggle = ref<boolean>(false);
const infoMenuRef = ref<any>(null); const infoMenuRef = ref<any>(null);
const walletAddressRef = ref<any>(null); const walletAddressRef = ref<any>(null);
const currencyRef = ref<any>(null); const currencyRef = ref<any>(null);
//Methods const { connectedWallet, connectedChain, setChain, disconnectWallet } =
useOnboard();
const connnectWallet = async (): Promise<void> => { const connnectWallet = async (): Promise<void> => {
await connectProvider(); const { connectWallet } = useOnboard();
await connectWallet();
}; };
watch(connectedWallet, async (newVal: any) => {
connectProvider(newVal.provider);
const addresses = await newVal.provider.request({ method: "eth_accounts" });
etherStore.setWalletAddress(addresses.shift());
});
watch(connectedChain, (newVal: any) => {
etherStore.setNetworkId(newVal?.id);
});
const formatWalletAddress = (): string => { const formatWalletAddress = (): string => {
const walletAddressLength = walletAddress.value.length; const walletAddressLength = walletAddress.value.length;
const initialText = walletAddress.value.substring(0, 5); const initialText = walletAddress.value.substring(0, 5);
@ -38,10 +56,10 @@ const formatWalletAddress = (): string => {
return `${initialText}...${finalText}`; return `${initialText}...${finalText}`;
}; };
const disconnectUser = (): void => { const disconnectUser = async (): Promise<void> => {
etherStore.setWalletAddress(""); etherStore.setWalletAddress("");
await disconnectWallet({ label: connectedWallet.value?.label || "" });
closeMenu(); closeMenu();
window.location.reload();
}; };
const closeMenu = (): void => { const closeMenu = (): void => {
@ -50,18 +68,23 @@ const closeMenu = (): void => {
const networkChange = async (network: NetworkEnum): Promise<void> => { const networkChange = async (network: NetworkEnum): Promise<void> => {
currencyMenuOpenToggle.value = false; currencyMenuOpenToggle.value = false;
const change = await requestNetworkChange(network); try {
if (change) etherStore.setNetworkName(network); await setChain({
chainId: Networks[network].chainId,
wallet: connectedWallet.value?.label || "",
});
etherStore.setNetworkId(network);
} catch (error) {
console.log("Error changing network", error);
}
}; };
onClickOutside(walletAddressRef, () => { onClickOutside(walletAddressRef, () => {
menuHoverToggle.value = false;
menuOpenToggle.value = false; menuOpenToggle.value = false;
}); });
onClickOutside(currencyRef, () => { onClickOutside(currencyRef, () => {
currencyMenuOpenToggle.value = false; currencyMenuOpenToggle.value = false;
currencyMenuHoverToggle.value = false;
}); });
onClickOutside(infoMenuRef, () => { onClickOutside(infoMenuRef, () => {
@ -74,17 +97,17 @@ onClickOutside(infoMenuRef, () => {
<RouterLink :to="'/'" class="default-button"> <RouterLink :to="'/'" class="default-button">
<img <img
alt="P2Pix logo" alt="P2Pix logo"
class="logo lg-view" class="logo hidden md:inline-block"
src="@/assets/logo.svg" width="200"
width="75"
height="75" height="75"
src="@/assets/logo.svg?url"
/> />
<img <img
alt="P2Pix logo" alt="P2Pix logo"
class="logo sm-view w-10/12" class="logo inline-block md:hidden w-10/12"
src="@/assets/logo2.svg"
width="40" width="40"
height="40" height="40"
src="@/assets/logo2.svg?url"
/> />
</RouterLink> </RouterLink>
@ -92,7 +115,7 @@ onClickOutside(infoMenuRef, () => {
<div class="flex flex-col"> <div class="flex flex-col">
<div <div
v-show="infoMenuOpenToggle" v-show="infoMenuOpenToggle"
class="mt-10 absolute w-full text-gray-900 lg-view" class="mt-10 absolute w-full text-gray-900 hidden md:inline-block"
> >
<div class="mt-2"> <div class="mt-2">
<div class="bg-white rounded-md z-10 -left-32 w-52"> <div class="bg-white rounded-md z-10 -left-32 w-52">
@ -120,41 +143,43 @@ onClickOutside(infoMenuRef, () => {
<div <div
class="sm:text-center sm:justify-center ml-8 sm:ml-0 gap-2 px-4 rounded-md float-right" class="sm:text-center sm:justify-center ml-8 sm:ml-0 gap-2 px-4 rounded-md float-right"
> >
<div class="redirect_button flex mr-4"> <div class="redirect_button">
<div class="mr-6"> <a
<a href="https://www.twitter.com/doiim"> href="https://www.twitter.com/doiim"
<img target="_blank"
alt="Twitter" rel="noreferrer"
width="20" >
height="20" <TwitterIcon
src="@/assets/twitterIcon.svg" alt="Twitter"
class="cursor-pointer" width="20"
/> height="20"
</a> class="cursor-pointer"
</div> />
<div class="mr-6"> </a>
<a href="https://www.linkedin.com/company/doiim/"> <a
<img href="https://www.linkedin.com/company/doiim/"
alt="LinkedIn" target="_blank"
width="20" rel="noreferrer"
height="20" >
src="@/assets/linkedinIcon.svg" <LinkedinIcon
class="cursor-pointer" alt="LinkedIn"
href="https://www.linkedin.com/company/doiim/" width="20"
/> height="20"
</a> class="cursor-pointer"
</div> />
<div class="mr-6"> </a>
<a href="https://www.github.com/doiim"> <a
<img href="https://www.github.com/doiim"
alt="Github" target="_blank"
width="20" rel="noreferrer"
height="20" >
src="@/assets/githubIcon.svg" <GithubIcon
class="cursor-pointer" alt="Github"
/> width="20"
</a> height="20"
</div> class="cursor-pointer"
/>
</a>
</div> </div>
</div> </div>
<div class="w-full flex justify-center"> <div class="w-full flex justify-center">
@ -165,7 +190,7 @@ onClickOutside(infoMenuRef, () => {
</div> </div>
<div <div
ref="infoMenuRef" ref="infoMenuRef"
class="default-button lg-view cursor-pointer" class="default-button hidden md:inline-block cursor-pointer"
@click=" @click="
[ [
(infoMenuOpenToggle = !infoMenuOpenToggle), (infoMenuOpenToggle = !infoMenuOpenToggle),
@ -189,27 +214,27 @@ onClickOutside(infoMenuRef, () => {
<RouterLink <RouterLink
:to="'/faq'" :to="'/faq'"
v-if="!walletAddress" v-if="!walletAddress"
class="default-button sm-view" class="default-button inline-block md:hidden"
> >
FAQ FAQ
</RouterLink> </RouterLink>
<RouterLink <RouterLink
:to="sellerView ? '/' : '/seller'" :to="sellerView ? '/' : '/seller'"
class="default-button sm:whitespace-normal whitespace-nowrap lg-view" class="default-button sm:whitespace-normal whitespace-nowrap hidden md:inline-block"
> >
{{ sellerView ? "Quero comprar" : "Quero vender" }} {{ sellerView ? "Quero comprar" : "Quero vender" }}
</RouterLink> </RouterLink>
<RouterLink <RouterLink
:to="sellerView ? '/' : '/seller'" :to="sellerView ? '/' : '/seller'"
v-if="!walletAddress" v-if="!walletAddress"
class="default-button sm:whitespace-normal whitespace-nowrap sm-view" class="default-button sm:whitespace-normal whitespace-nowrap inline-block md:hidden"
> >
{{ sellerView ? "Quero comprar" : "Quero vender" }} {{ sellerView ? "Quero comprar" : "Quero vender" }}
</RouterLink> </RouterLink>
<div class="flex flex-col" v-if="walletAddress"> <div class="flex flex-col" v-if="walletAddress">
<div <div
ref="currencyRef" ref="currencyRef"
class="group top-bar-info cursor-pointer hover:bg-white h-10" class="group top-bar-info cursor-pointer h-10"
@click=" @click="
[ [
(currencyMenuOpenToggle = !currencyMenuOpenToggle), (currencyMenuOpenToggle = !currencyMenuOpenToggle),
@ -217,15 +242,6 @@ onClickOutside(infoMenuRef, () => {
(infoMenuOpenToggle = false), (infoMenuOpenToggle = false),
] ]
" "
@mouseover="currencyMenuHoverToggle = true"
@mouseout="currencyMenuHoverToggle = false"
:style="{
backgroundColor: currencyMenuOpenToggle
? '#F9F9F9'
: currencyMenuHoverToggle
? '#F9F9F9'
: 'transparent',
}"
> >
<img <img
alt="Choosed network image" alt="Choosed network image"
@ -233,38 +249,18 @@ onClickOutside(infoMenuRef, () => {
height="24" height="24"
width="24" width="24"
/> />
<span <span class="default-text hidden md:inline-block">
class="default-text group-hover:text-gray-900 lg-view"
:style="{
color: currencyMenuOpenToggle
? '#000000'
: currencyMenuHoverToggle
? '#000000'
: 'rgb(249 250 251)',
}"
>
{{ Networks[etherStore.networkName].chainName }} {{ Networks[etherStore.networkName].chainName }}
</span> </span>
<img <ChevronDown
class="text-gray-900" class="pr-4 sm:pr-0 transition-all duration-300 ease-in-out"
v-if="!currencyMenuHoverToggle && !currencyMenuOpenToggle" :class="{ 'scale-y-[-1]': currencyMenuOpenToggle }"
alt="Chevron Down" alt="Chevron Down"
src="@/assets/chevronDown.svg"
/>
<img
v-if="currencyMenuOpenToggle"
alt="Chevron Up"
src="@/assets/chevronUp.svg"
/>
<img
v-if="currencyMenuHoverToggle && !currencyMenuOpenToggle"
alt="Chevron Down Black"
src="@/assets/chevronDownBlack.svg"
/> />
</div> </div>
<div <div
v-show="currencyMenuOpenToggle" v-show="currencyMenuOpenToggle"
class="mt-10 pl-3 absolute w-full text-gray-900 lg-view" class="mt-10 pl-3 absolute w-full text-gray-900 hidden md:inline-block"
> >
<div class="mt-2"> <div class="mt-2">
<div class="bg-white rounded-md z-10"> <div class="bg-white rounded-md z-10">
@ -294,7 +290,7 @@ onClickOutside(infoMenuRef, () => {
<button <button
type="button" type="button"
v-if="!walletAddress" v-if="!walletAddress"
class="border-amber-500 border-2 rounded default-button lg-view" class="border-amber-500 border-2 rounded default-button hidden md:inline-block"
@click="connnectWallet()" @click="connnectWallet()"
> >
Conectar carteira Conectar carteira
@ -302,7 +298,7 @@ onClickOutside(infoMenuRef, () => {
<button <button
type="button" type="button"
v-if="!walletAddress" v-if="!walletAddress"
class="border-amber-500 border-2 rounded default-button sm-view" class="border-amber-500 border-2 rounded default-button inline-block md:hidden"
@click="connnectWallet()" @click="connnectWallet()"
> >
Conectar Conectar
@ -319,65 +315,39 @@ onClickOutside(infoMenuRef, () => {
(infoMenuOpenToggle = false), (infoMenuOpenToggle = false),
] ]
" "
@mouseover="menuHoverToggle = true"
@mouseout="menuHoverToggle = false"
:style="{
backgroundColor: menuOpenToggle
? '#F9F9F9'
: menuHoverToggle
? '#F9F9F9'
: 'transparent',
}"
> >
<img alt="Account image" src="@/assets/account.svg" /> <Account alt="Account image" />
<span <span class="default-text">
class="default-text"
:style="{
color: menuOpenToggle
? '#000000'
: menuHoverToggle
? '#000000'
: 'rgb(249 250 251)',
}"
>
{{ formatWalletAddress() }} {{ formatWalletAddress() }}
</span> </span>
<img <ChevronDown
class="text-gray-900" class="pr-4 sm:pr-0 transition-all duration-300 ease-in-out"
v-if="!menuHoverToggle && !menuOpenToggle" :class="{ 'scale-y-[-1]': menuOpenToggle }"
alt="Chevron Down" alt="Chevron Down"
src="@/assets/chevronDown.svg"
/>
<img
v-if="menuOpenToggle"
alt="Chevron Up"
src="@/assets/chevronUp.svg"
/>
<img
v-if="menuHoverToggle && !menuOpenToggle"
alt="Chevron Down Black"
src="@/assets/chevronDownBlack.svg"
/> />
</div> </div>
<div <div
v-show="menuOpenToggle" v-show="menuOpenToggle"
class="mt-10 absolute w-full text-gray-900 lg-view" class="mt-10 absolute w-full text-gray-900 hidden md:inline-block"
> >
<div class="pl-4 mt-2"> <div class="pl-4 mt-2">
<div class="bg-white rounded-md z-10"> <div class="bg-white rounded-md z-10">
<div class="menu-button" @click="closeMenu()"> <RouterLink
<RouterLink to="/manage_bids" class="redirect_button"> onclick="closeMenu()"
Gerenciar Ofertas to="/manage_bids"
</RouterLink> class="redirect_button menu-button"
</div> >
Gerenciar Ofertas
</RouterLink>
<div class="w-full flex justify-center"> <div class="w-full flex justify-center">
<hr class="w-4/5" /> <hr class="w-4/5" />
</div> </div>
<div class="menu-button" @click="disconnectUser"> <button
<RouterLink to="/" class="redirect_button"> onclick="disconnectUser()"
Desconectar class="redirect_button menu-button"
</RouterLink> >
</div> Desconectar
</button>
</div> </div>
</div> </div>
</div> </div>
@ -386,7 +356,7 @@ onClickOutside(infoMenuRef, () => {
</div> </div>
<div <div
v-show="menuOpenToggle" v-show="menuOpenToggle"
class="mobile-menu fixed w-4/5 text-gray-900 sm-view" class="mobile-menu fixed w-4/5 text-gray-900 inline-block md:hidden"
> >
<div class="pl-4 mt-2 h-full"> <div class="pl-4 mt-2 h-full">
<div class="bg-white rounded-md z-10 h-full"> <div class="bg-white rounded-md z-10 h-full">
@ -417,48 +387,41 @@ onClickOutside(infoMenuRef, () => {
<div class="w-full flex justify-center"> <div class="w-full flex justify-center">
<hr class="w-4/5" /> <hr class="w-4/5" />
</div> </div>
<div class="menu-button pb-10"> <div class="redirect_button mx-10">
<div class="redirect_button flex"> <a
<a href="https://www.twitter.com/doiim/"> href="https://www.twitter.com/doiim/"
<img target="_blank"
alt="Twitter" rel="noreferrer"
width="20" >
height="20" <TwitterIcon alt="Twitter" width="20" height="20" />
src="@/assets/twitterIcon.svg" </a>
class="mr-6" <a
onclick="location.href = 'https://www.twitter.com/doiim';" href="https://www.linkedin.com/company/doiim/"
/> target="_blank"
</a> rel="noreferrer"
<a href="https://www.linkedin.com/company/doiim/"> >
<img <LinkedinIcon alt="LinkedIn" width="20" height="20" />
alt="LinkedIn" </a>
width="20" <a
height="20" href="https://github.com/doiim/"
src="@/assets/linkedinIcon.svg" target="_blank"
class="mr-6" rel="noreferrer"
/> >
</a> <GithubIcon alt="Github" width="20" height="20" />
<a href="https://github.com/doiim/"> </a>
<img
alt="Github"
width="20"
height="20"
src="@/assets/githubIcon.svg"
/>
</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div <div
v-show="currencyMenuOpenToggle" v-show="currencyMenuOpenToggle"
class="mobile-menu fixed w-4/5 text-gray-900 sm-view" class="mobile-menu fixed w-4/5 text-gray-900 inline-block sm:hidden"
> >
<div class="pl-4 mt-2 h-full"> <div class="pl-4 mt-2 h-full">
<div class="bg-white rounded-md z-10 h-full"> <div class="bg-white rounded-md z-10 h-full">
<div <div
v-for="(chainData, network) in Networks" v-for="(chainData, network) in Networks"
:key="network"
class="menu-button gap-2 sm:px-4 rounded-md cursor-pointer py-2" class="menu-button gap-2 sm:px-4 rounded-md cursor-pointer py-2"
@click="networkChange(network)" @click="networkChange(network)"
> >
@ -500,38 +463,20 @@ header {
} }
.redirect_button { .redirect_button {
@apply py-5 text-gray-900 sm:font-semibold font-bold sm:text-xs text-sm w-full; @apply py-5 px-4 text-gray-900 flex sm:font-semibold font-bold sm:text-xs text-sm justify-between;
} }
.menu-button { .menu-button {
@apply flex sm:text-center sm:justify-center hover:bg-gray-200 ml-8 sm:ml-0; @apply flex sm:text-center sm:justify-center hover:bg-gray-200 hover:rounded-lg w-full;
} }
a:hover { a:hover {
@apply bg-gray-200 rounded; @apply bg-gray-200 rounded;
} }
.lg-view {
display: inline-block;
}
.sm-view {
display: none;
}
.mobile-menu { .mobile-menu {
margin-top: 1400px; margin-top: 1400px;
bottom: 0px; bottom: 0px;
height: auto; height: auto;
} }
@media screen and (max-width: 500px) {
.lg-view {
display: none;
}
.sm-view {
display: inline-block;
}
}
</style> </style>

View File

@ -1,10 +1,9 @@
export enum NetworkEnum { export enum NetworkEnum {
ethereum = 11155111, sepolia = 11155111,
polygon = 80001,
rootstock = 31, rootstock = 31,
} }
export enum TokenEnum { export enum TokenEnum {
BRZ = 'BRZ', BRZ = "BRZ",
BRX = 'BRX' // BRX = 'BRX'
} }

View File

@ -1,41 +1,22 @@
import { NetworkEnum } from "@/model/NetworkEnum"; import { NetworkEnum } from "@/model/NetworkEnum";
export const Networks = { export const Networks = {
[NetworkEnum.ethereum]: [NetworkEnum.sepolia]: {
{ chainId: "0xAA36A7",
chainId: "0xAA36A7", chainName: "Sepolia Testnet",
chainName: "Sepolia" },
[NetworkEnum.rootstock]: {
chainId: "0x1F",
chainName: "Rootstock Testnet",
rpcUrls: ["https://public-node.testnet.rsk.co/"],
iconUrls: [
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAoCAYAAACWwljjAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAPOSURBVHgBxVhNUhpBFH6vGdxp4S4LoSYnEE8gnEA4AbpMJUQ4gXgCRJK1egLxBOIJJCdwJElVllMu49Cd1z04zD/dY1H5qihmut/M93VPv59uhHdAXFaPAaEDgA2/BaeA4hq/zG+gIBAKQoyr9yshid4Jdn+2oQAYFIC4rA2zxUhgS3yrDqEAjGdIDD/YYG09aRl7L7vYd10wgPkMlcoNfdvtFhjCXJBAeyO2S5gLQuFo25bEIxjCCt8oN2Z46I+Mu4A4SbjwojQBi1+BDl5LP+JNYlhtQRmPsjjQN1ILldwY7JTXOuD9bWL/jxO8dFy7oL9TyMcIu/PeSghxlLduQUA9jwPXiAk98HLw5jFiaFfAEjRLImPR0qi7z+2VmArZ7zzqcDAS01ljCKqf7QSjxb7jKkIhTohu6rOCq64RjsNiFEo7x7ocSNMvlddhPWb0CQ6gAAw4HKZpKGFDcWhzSEG6kbQCm4dLbi9m+XlpBTHea2D31zTSNtxrAGMNdcP5FPuxfhlKdCHgASUJxcd7zUcobkAPXvkzWGyf7uVCt2M2DtkMljaHSxu92WWLAz8OjWsD+juD/4tzcpqBSh3yQrmwoNFFMZNuDB7bJRsp/hzMMQqeT+NQ96KtNEBK+SG+23XgHgUyy8FPjpPozy3M4sZwh1/nLRMOK26Mn50Z5IHjA6XkBugJSn1XHkeBbK8dJsxsl0jMEOUpm0o9+gkX+7+TI0E+0x6Hsk0ijyNYQ/4OAqWn2aF+5cLxEoRq6idqtyEPtFhp/XyMNI2p9ADFUc/iYL5h7YzEXEEyptj04mvVHxkGP4F8MS4sWDsqRr4DbyGZRiIcqCKtpRMYeTMcpVVAFewqMVPSjUkMVQTBp6BPVKeiTqN65E0qP1AvIArWC98qcQsms39oDeBEtoXFKFgLbQ76ZKiXiRH2E01UF9Go+kGDh32/LWHZAD2OQ7mGdLO4ndrqWaHZyNyD6XJUWEq6yIQqReOweCe49ivD2DNUIutjJgXpHwyUtyPbY/IMWehfBA0IZxQSQoW9rKXL+ltq0oKqYC+RB6yLKys4xEw/Idde5R02cTGOcgh1LSNnid+nihIqcN0tr48MhL89L2uoG+Dqv5Px/IwqAhkqnEi296M1OyLPqVCgdKhcuKNjlUnQL4X78cRk1E1JlMkBME1sFE0gRrRJZGs3iT44bRZP5z0wQJHzIZMMbpztN1t+FDhsMBe0YNfatimHDetgLGiZGkYapqPwYt6YIAWPDYI9fSrETfjkwwSFT2EVrV/USY+r+/GGNp2I7zoW/gdR9aOdZ/lPGgAAAABJRU5ErkJggg==",
],
nativeCurrency: {
name: "tRBTC",
symbol: "tRBTC",
decimals: 18,
}, },
[NetworkEnum.polygon]: blockExplorerUrls: ["https://explorer.testnet.rootstock.io/"],
{ },
chainId: "0x13881", };
chainName: "Polygon Mumbai",
nativeCurrency: {
name: "MATIC",
symbol: "MATIC",
decimals: 18
},
blockExplorerUrls: [
"https://mumbai.polygonscan.com/"
]
},
[NetworkEnum.rootstock]:
{
chainId: "0x1F",
chainName: "Rootstock Testnet",
rpcUrls: [
"https://public-node.testnet.rsk.co/"
],
iconUrls: [
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAoCAYAAACWwljjAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAPOSURBVHgBxVhNUhpBFH6vGdxp4S4LoSYnEE8gnEA4AbpMJUQ4gXgCRJK1egLxBOIJJCdwJElVllMu49Cd1z04zD/dY1H5qihmut/M93VPv59uhHdAXFaPAaEDgA2/BaeA4hq/zG+gIBAKQoyr9yshid4Jdn+2oQAYFIC4rA2zxUhgS3yrDqEAjGdIDD/YYG09aRl7L7vYd10wgPkMlcoNfdvtFhjCXJBAeyO2S5gLQuFo25bEIxjCCt8oN2Z46I+Mu4A4SbjwojQBi1+BDl5LP+JNYlhtQRmPsjjQN1ILldwY7JTXOuD9bWL/jxO8dFy7oL9TyMcIu/PeSghxlLduQUA9jwPXiAk98HLw5jFiaFfAEjRLImPR0qi7z+2VmArZ7zzqcDAS01ljCKqf7QSjxb7jKkIhTohu6rOCq64RjsNiFEo7x7ocSNMvlddhPWb0CQ6gAAw4HKZpKGFDcWhzSEG6kbQCm4dLbi9m+XlpBTHea2D31zTSNtxrAGMNdcP5FPuxfhlKdCHgASUJxcd7zUcobkAPXvkzWGyf7uVCt2M2DtkMljaHSxu92WWLAz8OjWsD+juD/4tzcpqBSh3yQrmwoNFFMZNuDB7bJRsp/hzMMQqeT+NQ96KtNEBK+SG+23XgHgUyy8FPjpPozy3M4sZwh1/nLRMOK26Mn50Z5IHjA6XkBugJSn1XHkeBbK8dJsxsl0jMEOUpm0o9+gkX+7+TI0E+0x6Hsk0ijyNYQ/4OAqWn2aF+5cLxEoRq6idqtyEPtFhp/XyMNI2p9ADFUc/iYL5h7YzEXEEyptj04mvVHxkGP4F8MS4sWDsqRr4DbyGZRiIcqCKtpRMYeTMcpVVAFewqMVPSjUkMVQTBp6BPVKeiTqN65E0qP1AvIArWC98qcQsms39oDeBEtoXFKFgLbQ76ZKiXiRH2E01UF9Go+kGDh32/LWHZAD2OQ7mGdLO4ndrqWaHZyNyD6XJUWEq6yIQqReOweCe49ivD2DNUIutjJgXpHwyUtyPbY/IMWehfBA0IZxQSQoW9rKXL+ltq0oKqYC+RB6yLKys4xEw/Idde5R02cTGOcgh1LSNnid+nihIqcN0tr48MhL89L2uoG+Dqv5Px/IwqAhkqnEi296M1OyLPqVCgdKhcuKNjlUnQL4X78cRk1E1JlMkBME1sFE0gRrRJZGs3iT44bRZP5z0wQJHzIZMMbpztN1t+FDhsMBe0YNfatimHDetgLGiZGkYapqPwYt6YIAWPDYI9fSrETfjkwwSFT2EVrV/USY+r+/GGNp2I7zoW/gdR9aOdZ/lPGgAAAABJRU5ErkJggg==",
],
nativeCurrency: {
name: "tRBTC",
symbol: "tRBTC",
decimals: 18
},
blockExplorerUrls: [
"https://explorer.testnet.rootstock.io/"
]
}
}

View File

@ -1,15 +1,12 @@
import { NetworkEnum, TokenEnum } from "../model/NetworkEnum"; import { NetworkEnum, TokenEnum } from "../model/NetworkEnum";
import type { ValidDeposit } from "@/model/ValidDeposit"; import type { ValidDeposit } from "@/model/ValidDeposit";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
export const useEtherStore = defineStore("ether", { export const useEtherStore = defineStore("ether", {
state: () => ({ state: () => ({
walletAddress: "", walletAddress: "",
balance: "", balance: "",
networkName: NetworkEnum.ethereum, networkName: NetworkEnum.sepolia,
selectedToken: TokenEnum.BRZ, selectedToken: TokenEnum.BRZ,
loadingLock: false, loadingLock: false,
sellerView: false, sellerView: false,
@ -32,7 +29,7 @@ export const useEtherStore = defineStore("ether", {
setSelectedToken(token: TokenEnum) { setSelectedToken(token: TokenEnum) {
this.selectedToken = token; this.selectedToken = token;
}, },
setNetworkName(networkName: NetworkEnum) { setNetworkId(networkName: NetworkEnum) {
this.networkName = Number(networkName); this.networkName = Number(networkName);
}, },
setLoadingLock(isLoadingLock: boolean) { setLoadingLock(isLoadingLock: boolean) {

View File

@ -1,17 +1,21 @@
import type { NetworkEnum, TokenEnum } from "@/model/NetworkEnum"; import type { TokenEnum } from "@/model/NetworkEnum";
export const imagesPath = import.meta.glob<string>('@/assets/*.{png,svg}', { eager: true, query: '?url', import: 'default' }); export const imagesPath = import.meta.glob<string>("@/assets/*.{png,svg}", {
eager: true,
query: "?url",
import: "default",
});
export const getNetworkImage = (networkName: string): string => { export const getNetworkImage = (networkName: string): string => {
const path = Object.keys(imagesPath).find((key) => const path = Object.keys(imagesPath).find((key) =>
key.endsWith(`${networkName.toLowerCase()}.svg`) key.endsWith(`${networkName.toLowerCase()}.svg`)
); );
return path ? imagesPath[path] : ""; return path ? imagesPath[path] : "";
}; };
export const getTokenImage = (tokenName: TokenEnum): string => { export const getTokenImage = (tokenName: TokenEnum): string => {
const path = Object.keys(imagesPath).find((key) => const path = Object.keys(imagesPath).find((key) =>
key.endsWith(`${tokenName.toLowerCase()}.svg`) key.endsWith(`${tokenName.toLowerCase()}.svg`)
); );
return path ? imagesPath[path] : ""; return path ? imagesPath[path] : "";
}; };

View File

@ -61,13 +61,13 @@ const openItem = (index: number) => {
<div class="flex cursor-pointer" @click="openItem(index)"> <div class="flex cursor-pointer" @click="openItem(index)">
<img <img
alt="plus" alt="plus"
src="@/assets/plus.svg" src="@/assets/plus.svg?url"
class="mr-3" class="mr-3"
v-if="!item.isOpen" v-if="!item.isOpen"
/> />
<img <img
alt="plus" alt="plus"
src="@/assets/minus.svg" src="@/assets/minus.svg?url"
class="mr-3" class="mr-3"
v-if="item.isOpen" v-if="item.isOpen"
/> />
@ -135,10 +135,10 @@ h4 {
@apply text-white text-center; @apply text-white text-center;
} }
.blur-container-row { .blur-container-row {
@apply flex flex-row justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 w-1/3; @apply flex flex-row justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 max-w-screen-sm;
} }
.blur-container { .blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 w-1/3; @apply flex flex-col justify-center items-center px-8 py-6 gap-2 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-8 max-w-screen-sm;
} }
</style> </style>

View File

@ -107,6 +107,7 @@ if (paramLockID) {
}); });
watch(networkName, async () => { watch(networkName, async () => {
console.log(walletAddress.value);
if (walletAddress.value) await checkForUnreleasedLocks(); if (walletAddress.value) await checkForUnreleasedLocks();
}); });
} }

View File

@ -1,8 +1,15 @@
{ {
"extends": "@vue/tsconfig/tsconfig.node.json", "extends": "@vue/tsconfig/tsconfig.node.json",
"include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"], "include": [
"vite.config.*",
"vitest.config.*",
"cypress.config.*",
"playwright.config.*"
],
"compilerOptions": { "compilerOptions": {
"composite": true, "composite": true,
"types": ["node"] "types": [
"node"
]
} }
} }

View File

@ -1,15 +1,23 @@
{ {
"extends": "@vue/tsconfig/tsconfig.web.json", "extends": "@vue/tsconfig/tsconfig.web.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"], "include": [
"env.d.ts",
"src/**/*",
"src/**/*.vue"
],
"compilerOptions": { "compilerOptions": {
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@/*": ["./src/*"] "@/*": [
"./src/*"
]
}, },
"types": ["jest", "node"], "types": [
"jest",
"node"
],
"resolveJsonModule": true "resolveJsonModule": true
}, },
"references": [ "references": [
{ {
"path": "./tsconfig.config.json" "path": "./tsconfig.config.json"

View File

@ -3,9 +3,21 @@ import { fileURLToPath, URL } from "node:url";
import { defineConfig } from "vitest/config"; import { defineConfig } from "vitest/config";
import vue from "@vitejs/plugin-vue"; import vue from "@vitejs/plugin-vue";
import vueJsx from "@vitejs/plugin-vue-jsx"; import vueJsx from "@vitejs/plugin-vue-jsx";
import svgLoader from "vite-svg-loader";
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
optimizeDeps: {
esbuildOptions: {
target: "esnext",
define: {
global: "globalThis",
},
supported: {
bigint: true,
},
},
},
test: { test: {
globals: true, globals: true,
environment: "jsdom", environment: "jsdom",
@ -17,16 +29,10 @@ export default defineConfig({
reporter: ["text", "lcov", "html"], reporter: ["text", "lcov", "html"],
}, },
}, },
plugins: [vue(), vueJsx()], plugins: [vue(), vueJsx(), svgLoader()],
resolve: { resolve: {
alias: { alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)), "@": fileURLToPath(new URL("./src", import.meta.url)),
}, },
}, },
build: {
target: "esnext", // Or a recent target that supports BigInt literals
rollupOptions: {
external: ["@coinbase/wallet-sdk"], // Exclude from the bundle if needed
},
},
}); });

1149
yarn.lock

File diff suppressed because it is too large Load Diff