Merge pull request #9 from liftlearning/list-tokens

List tokens screen and steps integration (Search, Buy and List)
This commit is contained in:
Rafael Ramos 2022-12-20 09:02:26 -03:00 committed by GitHub
commit fbf14ee86f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1229 additions and 201 deletions

View File

@ -11,10 +11,15 @@ jobs:
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID_STAGING }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_STAGING }}
ENV_VARIABLE: ${{ secrets.ENV_STAGING }}
steps:
- name: 🏗 Setup repo
uses: actions/checkout@v3
- name: 🏗 Config .env
run: echo "$ENV_VARIABLE" > .env
- name: 🏗 Install Vercel CLI
run: npm install --global vercel@latest
@ -33,10 +38,15 @@ jobs:
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
ENV_VARIABLE: ${{ secrets.ENV_PROD }}
steps:
- name: 🏗 Setup repo
uses: actions/checkout@v3
- name: 🏗 Config .env
run: echo "$ENV_VARIABLE" > .env
- name: 🏗 Install Vercel CLI
run: npm install --global vercel@latest

View File

@ -23,19 +23,18 @@ jobs:
build:
runs-on: ubuntu-latest
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID_STAGING }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID_STAGING }}
steps:
- name: 🏗 Setup repo
uses: actions/checkout@v3
- name: 📦 Build docker image
run: |
docker build -t p2pix:$GITHUB_SHA .
docker save -o image_$GITHUB_SHA p2pix:$GITHUB_SHA
- name: 🏗 Install Vercel CLI
run: npm install --global vercel@latest
- name: 📦 Put docker image in cache
uses: actions/cache@v3
with:
key: p2pix
path: image_${{ github.sha }}
- name: 🏗 Pull staging app from vercel environment
run: vercel pull --yes --token=${{ secrets.VERCEL_AUTH_TOKEN }}
# test job
- name: 📦 Build staging app artifacts
run: vercel build --token=${{ secrets.VERCEL_AUTH_TOKEN }}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 3.9 MiB

After

Width:  |  Height:  |  Size: 744 KiB

3
src/assets/redirect.svg Normal file
View File

@ -0,0 +1,3 @@
<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="M9.97059 0.888889C9.97059 0.397969 10.3686 0 10.8595 0H15.1111C15.602 0 16 0.397969 16 0.888889V5.23654C16 5.72746 15.602 6.12543 15.1111 6.12543C14.6202 6.12543 14.2222 5.72746 14.2222 5.23654V3.06921L8.66058 8.75646C8.31735 9.10744 7.75457 9.11373 7.40358 8.77049C7.05259 8.42726 7.04631 7.86448 7.38954 7.51349L12.9986 1.77778H10.8595C10.3686 1.77778 9.97059 1.37981 9.97059 0.888889ZM2.74997 2.67823C2.11751 2.67823 1.77778 3.11618 1.77778 3.45456V13.4459C1.77778 13.7843 2.11751 14.2222 2.74997 14.2222H12.0554C12.6878 14.2222 13.0275 13.7843 13.0275 13.4459V9.98736C13.0275 9.49644 13.4255 9.09847 13.9164 9.09847C14.4073 9.09847 14.8053 9.49644 14.8053 9.98736V13.4459C14.8053 14.9469 13.4786 16 12.0554 16H2.74997C1.32673 16 0 14.9469 0 13.4459V3.45456C0 1.9536 1.32673 0.900455 2.74997 0.900455H5.89948C6.3904 0.900455 6.78837 1.29842 6.78837 1.78934C6.78837 2.28026 6.3904 2.67823 5.89948 2.67823H2.74997Z" fill="#111827"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,151 @@
<script setup lang="ts">
import CustomButton from "@/components/CustomButton.vue";
import blockchain from "../utils/blockchain";
// props
const props = defineProps<{
lastWalletReleaseTransactions: any[] | undefined;
tokenAmount: Number | undefined;
}>();
// Emits
const emit = defineEmits(["makeAnotherTransaction"]);
const formatEventsAmount = (amount: any) => {
try {
const formated = blockchain.formatBigNumber(amount);
return formated;
} catch {
return "";
}
};
const openEtherscanUrl = (url: string) => {
window.open(url, "_blank");
};
</script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-extrabold text-5xl max-w-[50rem]"
>Os tokens foram transferidos <br />
para a sua carteira!
</span>
</div>
<div class="blur-container">
<div
class="flex flex-col w-full bg-white px-10 py-5 rounded-lg border-y-10"
>
<div>
<p>Tokens recebidos</p>
<p class="text-2xl text-gray-900">{{ props.tokenAmount }} BRZ</p>
</div>
<div class="my-5">
<p>
<b>Não encontrou os tokens? </b>Clique no botão abaixo para <br />
cadastrar o BRZ em sua carteira.
</p>
</div>
<CustomButton
:text="'Cadastrar token na carteira'"
@buttonClicked="() => {}"
/>
</div>
<button
type="button"
class="border-amber-500 border-2 rounded default-button text-white p-2 px-50 min-w-[198px]"
@click="emit('makeAnotherTransaction')"
>
Fazer nova transação
</button>
</div>
<div class="text-container mt-16">
<span class="text font-extrabold text-3xl max-w-[50rem]"
>Últimas transações
</span>
</div>
<div class="blur-container min-w-[80%] gap-8">
<div class="flex flex-row justify-between w-full px-8">
<span class="text-xs text-gray-50 font-medium">Valor</span>
<span class="text-xs text-gray-50 font-medium">Tipo de transação</span>
<span class="text-xs text-gray-50 font-medium">Checar transação</span>
</div>
<div
class="flex flex-row justify-between w-full bg-white px-6 py-4 rounded-lg"
v-for="release in lastWalletReleaseTransactions"
:key="release?.blockNumber"
>
<span class="last-release-info">
{{ formatEventsAmount(release?.args.amount) }} BRZ
</span>
<span class="last-release-info">
{{ "Compra" }}
</span>
<div
class="flex gap-2 cursor-pointer items-center"
@click="
openEtherscanUrl(
`https://etherscan.io/tx/${release?.transactionHash}`
)
"
>
<span class="last-release-info">Etherscan</span>
<img alt="Redirect image" src="@/assets/redirect.svg" />
</div>
</div>
<div class="flex justify-center w-full right-6 mt-2">
<button
type="button"
class="text-white"
@click="() => {}"
v-if="lastWalletReleaseTransactions?.length != 0"
>
Carregar mais
</button>
</div>
<p class="font-bold" v-if="lastWalletReleaseTransactions?.length == 0">
Não nenhuma transação anterior
</p>
</div>
</div>
</template>
<style scoped>
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
p {
@apply text-gray-900;
}
.text-container {
@apply flex flex-col items-center justify-center gap-4;
}
.text {
@apply text-gray-800 text-center;
}
.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;
}
.blur-container {
@apply flex flex-col justify-center items-center px-8 py-6 gap-4 rounded-lg shadow-md shadow-gray-600 backdrop-blur-md mt-10 w-auto;
}
.last-release-info {
@apply font-medium text-base text-gray-900;
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}
</style>

View File

@ -1,10 +1,17 @@
<script setup lang="ts"></script>
<script setup lang="ts">
// prop
const props = defineProps({
title: String,
message: String,
});
</script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-bold text-3xl max-w-[29rem]"
>Confirme em sua carteira</span
>
<span class="text font-bold text-3xl max-w-[29rem]">{{
props.title ? props.title : "Confirme em sua carteira"
}}</span>
</div>
<div class="blur-container w-[26rem]">
<div
@ -20,7 +27,7 @@
height="48"
/>
<span class="text-black font-medium text-sm px-12 mt-4">
A transação está sendo enviada para a rede
{{ $props.message }}
</span>
</div>
</div>

View File

@ -5,6 +5,7 @@ import { debounce } from "@/utils/debounce";
import CustomButton from "./CustomButton.vue";
import api from "../services/index";
// props and store references
const props = defineProps({
pixTarget: String,
tokenValue: Number,
@ -12,13 +13,17 @@ const props = defineProps({
const qrCode = ref<string>("");
const qrCodePayload = ref<string>("");
const isPixValid = ref<boolean>(false);
const isCodeInputEmpty = ref<boolean>(true);
const e2eId = ref<string>("");
// Emits
const emit = defineEmits(["pixValidated"]);
const pixQrCode = pix({
pixKey: props.pixTarget ?? "",
value: props.tokenValue,
});
const isPixValid = ref<boolean>(false);
const isCodeInputEmpty = ref<boolean>(true);
pixQrCode.base64QrCode().then((code: string) => {
qrCode.value = code;
});
@ -27,12 +32,12 @@ qrCodePayload.value = pixQrCode.payload();
const handleInputEvent = (event: any) => {
const { value } = event.target;
validatePix(value);
e2eId.value = value;
validatePix();
};
const validatePix = async (e2eid: any) => {
if (e2eid == "") {
const validatePix = async () => {
if (e2eId.value == "") {
isPixValid.value = false;
isCodeInputEmpty.value = true;
return;
@ -42,7 +47,7 @@ const validatePix = async (e2eid: any) => {
if (sellerPixKey && transactionValue) {
var body_req = {
e2e_id: e2eid,
e2e_id: e2eId.value,
pix_key: sellerPixKey,
pix_value: transactionValue,
};
@ -141,6 +146,7 @@ const validatePix = async (e2eid: any) => {
<CustomButton
:is-disabled="isPixValid == false"
:text="'Enviar para a rede'"
@button-clicked="emit('pixValidated', { e2eId })"
/>
</div>
</div>

View File

@ -9,7 +9,7 @@ import blockchain from "../utils/blockchain";
// Store reference
const etherStore = useEtherStore();
const { walletAddress, depositsAddedList } = storeToRefs(etherStore);
const { walletAddress, depositsValidList } = storeToRefs(etherStore);
// Reactive state
const tokenValue = ref(0);
@ -52,18 +52,20 @@ const decimalCount = (num: Number) => {
}
return 0;
};
// Verify if there is a valid deposit to buy
const verifyLiquidity = () => {
enableSelectButton.value = false;
selectedDeposit.value = null;
if (!walletAddress.value || tokenValue.value <= 0) return;
depositsAddedList.value.find((element) => {
const p2pixTokenValue = blockchain.formatBigNumber(element.args.amount);
depositsValidList.value.find((element) => {
const remaining = element.remaining;
if (
tokenValue.value!! <= Number(p2pixTokenValue) &&
element.valid == true &&
tokenValue.value!! <= remaining &&
tokenValue.value!! != 0 &&
element.args.seller !== walletAddress.value
element.seller !== walletAddress.value
) {
enableSelectButton.value = true;
hasLiquidity.value = true;

View File

@ -0,0 +1,188 @@
<script setup lang="ts">
import { ref } from "vue";
import CustomButton from "../../components/CustomButton.vue";
import { debounce } from "@/utils/debounce";
import { useEtherStore } from "@/store/ether";
import { storeToRefs } from "pinia";
// Store reference
const etherStore = useEtherStore();
const { walletAddress, depositsAddedList } = storeToRefs(etherStore);
// Reactive state
const tokenValue = ref(0);
const enableSelectButton = ref(false);
const hasLiquidity = ref(true);
const validDecimals = ref(true);
const selectedDeposit = ref();
// Emits
const emit = defineEmits(["tokenBuy"]);
// Blockchain methods
const connectAccount = async () => {};
// Debounce methods
const handleInputEvent = (event: any) => {
const { value } = event.target;
tokenValue.value = Number(value);
if (decimalCount(tokenValue.value) > 2) {
validDecimals.value = false;
enableSelectButton.value = false;
return;
}
validDecimals.value = true;
// verifyLiquidity();
};
// Enable button methods
// Check if has more than 2 decimal places
const decimalCount = (num: Number) => {
const numStr = String(num);
if (numStr.includes(".")) {
return numStr.split(".")[1].length;
}
return 0;
};
// Verify if there is a valid deposit to buy
// const verifyLiquidity = () => {
// enableSelectButton.value = false;
// selectedDeposit.value = null;
// if (!walletAddress.value || tokenValue.value <= 0) return;
// depositsAddedList.value.find((element) => {
// const p2pixTokenValue = blockchain.formatBigNumber(element.args.amount);
// if (
// tokenValue.value!! <= Number(p2pixTokenValue) &&
// tokenValue.value!! != 0 &&
// element.args.seller !== walletAddress.value
// ) {
// enableSelectButton.value = true;
// hasLiquidity.value = true;
// selectedDeposit.value = element;
// return true;
// }
// return false;
// });
// if (!enableSelectButton.value) {
// hasLiquidity.value = false;
// }
// };
</script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-extrabold text-5xl max-w-[29rem]"
>Adquira cripto com apenas um Pix</span
>
<span class="text font-medium text-base max-w-[28rem]"
>Digite um valor, confira a oferta, conecte sua carteira e receba os
tokens após realizar o Pix</span
>
</div>
<div class="blur-container">
<div
class="flex flex-col w-full bg-white px-10 py-5 rounded-lg border-y-10"
>
<div class="flex justify-between w-full items-center">
<input
type="number"
class="border-none outline-none text-lg text-gray-900 w-fit"
v-bind:class="{
'font-semibold': tokenValue != undefined,
'text-xl': tokenValue != undefined,
}"
@input="debounce(handleInputEvent, 500)($event)"
placeholder="0 "
step=".01"
/>
<div
class="flex flex-row p-2 px-3 bg-gray-300 rounded-3xl min-w-fit gap-1"
>
<img alt="Token image" class="w-fit" src="@/assets/brz.svg" />
<span class="text-gray-900 text-lg w-fit" id="brz">BRZ</span>
</div>
</div>
<div class="custom-divide py-2"></div>
<div class="flex justify-between pt-2" v-if="hasLiquidity">
<p class="text-gray-500 font-normal text-sm w-auto">
~ R$ {{ tokenValue.toFixed(2) }}
</p>
<div class="flex gap-2">
<img
alt="Polygon image"
src="@/assets/polygon.svg"
width="24"
height="24"
/>
<img
alt="Ethereum image"
src="@/assets/ethereum.svg"
width="24"
height="24"
/>
</div>
</div>
<div class="flex pt-2 justify-center" v-if="!validDecimals">
<span class="text-red-500 font-normal text-sm"
>Por favor utilize no máximo 2 casas decimais</span
>
</div>
<div class="flex pt-2 justify-center" v-else-if="!hasLiquidity">
<span class="text-red-500 font-normal text-sm"
>Atualmente não liquidez nas redes para sua demanda</span
>
</div>
</div>
<CustomButton
:text="'Conectar carteira'"
@buttonClicked="emit('tokenBuy')"
/>
</div>
</div>
</template>
<style scoped>
.custom-divide {
width: 100%;
border-bottom: 1px solid #d1d5db;
}
.bottom-position {
top: -20px;
right: 50%;
transform: translateX(50%);
}
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
.text-container {
@apply flex flex-col items-center justify-center gap-4;
}
.text {
@apply text-gray-800 text-center;
}
.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-10;
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}
</style>

View File

@ -0,0 +1,90 @@
<script setup lang="ts">
import CustomButton from "@/components/CustomButton.vue";
// Emits
const emit = defineEmits(["sendNetwork"]);
const sendNetworkHandle = () => {
emit("sendNetwork");
};
</script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-extrabold text-5xl max-w-[50rem]"
>Envie sua oferta para a rede
</span>
<span class="text text-xl font-medium text-base max-w-[30rem]"
>Após a confirmação sua oferta estará disponível para outros usuários.
Caso deseje retirar a oferta, será necessário aguardar 24h para receber
os tokens de volta.</span
>
</div>
<div class="blur-container">
<div
class="flex flex-col w-full bg-white px-10 py-5 rounded-lg border-y-10"
>
<div>
<p>Tokens ofertados</p>
<p class="text-2xl text-gray-900">100 BRZ</p>
</div>
<div class="my-3">
<p>Chave Pix</p>
<p class="text-xl text-gray-900 break-words">
c02942far7047f6shri5ifh371908973
</p>
</div>
<div class="mb-5">
<p>
<b>Atenção! </b> Os tokens ofertados ficam registrados no smart
contract e serão transferidos automaticamente para o comprador assim
que o Pix for detectado e confirmado.
</p>
</div>
<CustomButton
:text="'Enviar para a rede'"
@buttonClicked="sendNetworkHandle()"
/>
</div>
</div>
</div>
</template>
<style scoped>
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
p {
@apply text-gray-900;
}
.text-container {
@apply flex flex-col items-center justify-center gap-4;
}
.text {
@apply text-gray-800 text-center;
}
.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;
}
.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;
}
.last-deposit-info {
@apply font-medium text-base;
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}
</style>

View File

@ -0,0 +1,150 @@
<script setup lang="ts">
import { ref } from "vue";
import CustomButton from "../CustomButton.vue";
import { debounce } from "@/utils/debounce";
// Reactive state
const offer = ref<string | number>("");
const pixKey = ref<string>("");
const enableSelectButton = ref(false);
const hasLiquidity = ref(true);
const validDecimals = ref(true);
// Emits
const emit = defineEmits(["approveTokens"]);
// Blockchain methods
const approveTokensHandle = async () => {
console.log(offer.value, pixKey.value);
emit("approveTokens");
};
// Debounce methods
const handleInputEvent = (event: any) => {
const { value } = event.target;
offer.value = Number(value);
if (decimalCount(offer.value) > 2) {
validDecimals.value = false;
enableSelectButton.value = false;
return;
}
validDecimals.value = true;
};
// Enable button methods
// Check if has more than 2 decimal places
const decimalCount = (num: Number) => {
const numStr = String(num);
if (numStr.includes(".")) {
return numStr.split(".")[1].length;
}
return 0;
};
</script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-extrabold text-5xl max-w-[29rem]"
>Venda cripto e receba em Pix</span
>
<span class="text font-medium text-base max-w-[28rem]"
>Digite sua oferta, informe a chave Pix, selecione a rede, aprove o
envio da transação e confirme sua oferta.</span
>
</div>
<div class="blur-container">
<div
class="flex flex-col w-full bg-white px-10 py-5 rounded-lg border-y-10"
>
<div class="flex justify-between w-full items-center">
<input
type="number"
v-model="offer"
class="border-none outline-none text-lg text-gray-900 w-fit"
v-bind:class="{
'font-semibold': offer != undefined,
'text-xl': offer != undefined,
}"
@input="debounce(handleInputEvent, 500)($event)"
placeholder="Digite sua oferta"
step=".01"
/>
<div
class="flex flex-row p-2 px-3 bg-gray-300 rounded-3xl min-w-fit gap-1"
>
<img alt="Token image" class="w-fit" src="@/assets/brz.svg" />
<span class="text-gray-900 text-lg w-fit" id="brz">BRZ</span>
</div>
</div>
<div class="flex pt-2 justify-center" v-if="!validDecimals">
<span class="text-red-500 font-normal text-sm"
>Por favor utilize no máximo 2 casas decimais</span
>
</div>
<div class="flex pt-2 justify-center" v-else-if="!hasLiquidity">
<span class="text-red-500 font-normal text-sm"
>Atualmente não liquidez nas redes para sua demanda</span
>
</div>
</div>
<div
class="flex flex-col w-full bg-white px-10 py-8 rounded-lg border-y-10"
>
<div class="flex justify-between w-full items-center">
<input
type="text"
v-model="pixKey"
class="border-none outline-none text-lg text-gray-900 w-fit"
placeholder="Digite a chave Pix"
/>
</div>
</div>
<CustomButton
:text="'Aprovar tokens'"
@buttonClicked="approveTokensHandle()"
/>
</div>
</div>
</template>
<style scoped>
.custom-divide {
width: 100%;
border-bottom: 1px solid #d1d5db;
}
.bottom-position {
top: -20px;
right: 50%;
transform: translateX(50%);
}
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
.text-container {
@apply flex flex-col items-center justify-center gap-4;
}
.text {
@apply text-gray-800 text-center;
}
.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-10;
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}
</style>

View File

@ -1,4 +1,5 @@
<script setup lang="ts">
import router from "@/router";
import { storeToRefs } from "pinia";
import { useEtherStore } from "../store/ether";
import blockchain from "../utils/blockchain";
@ -23,11 +24,9 @@ const formatWalletAddress = (): string => {
return `${initialText}...${finalText}`;
};
const formatWalletBalance = (): string => {
const formattedBalance = blockchain.formatEther(balance.value);
const fixed = formattedBalance.substring(0, 8);
return fixed;
const formatWalletBalance = (): String => {
const fixed = Number(balance.value);
return fixed.toFixed(2);
};
</script>
@ -41,7 +40,13 @@ const formatWalletBalance = (): string => {
height="75"
/>
<div class="flex gap-4 items-center">
<button type="button" class="default-button">Quero vender</button>
<button
type="button"
class="default-button"
v-on:click="router.push('/seller')"
>
Quero vender
</button>
<button
type="button"
v-if="!walletAddress"

View File

@ -1,6 +1,7 @@
import { createRouter, createWebHistory } from "vue-router";
import HomeView from "../views/HomeView.vue";
import MockView from "../views/MockView.vue";
import SellerView from "@/views/SellerView.vue";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@ -10,6 +11,11 @@ const router = createRouter({
name: "home",
component: HomeView,
},
{
path: "/seller",
name: "seller",
component: SellerView,
},
{
path: "/mock",
name: "mock",

View File

@ -13,6 +13,10 @@ export const useEtherStore = defineStore("ether", {
depositsExpiredList: [] as any[],
// Locks adicionados na blockchain
locksAddedList: [] as any[],
// Locks 'released' na blockchain
locksReleasedList: [] as any[],
// Locks expirados na blockchain
locksExpiredList: [] as any[],
}),
actions: {
setWalletAddress(walletAddress: string) {
@ -36,5 +40,11 @@ export const useEtherStore = defineStore("ether", {
setLocksAddedList(locksAddedList: any[]) {
this.locksAddedList = locksAddedList;
},
setLocksReleasedList(locksReleasedList: any[]) {
this.locksReleasedList = locksReleasedList;
},
setLocksExpiredList(locksExpiredList: any[]) {
this.locksExpiredList = locksExpiredList;
},
},
});

View File

@ -8,15 +8,28 @@ import addresses from "./smart_contract_files/localhost.json";
// Mock wallets import
import { wallets } from "./smart_contract_files/wallets.json";
// Provider methods
const connectProvider = async () => {
// Wallet methods
// Update wallet state (balance and address)
const updateWalletStatus = async () => {
const etherStore = useEtherStore();
const window_ = window as any;
const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null;
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const contract = new ethers.Contract(addresses.token, mockToken.abi, signer);
const walletAddress = await provider.send("eth_requestAccounts", []);
const balance = await contract.balanceOf(walletAddress[0]);
etherStore.setBalance(formatBigNumber(balance));
etherStore.setWalletAddress(ethers.utils.getAddress(walletAddress[0]));
};
// Split tokens between wallets in wallets.json
const splitTokens = async () => {
const provider = getProvider();
if (!provider) return;
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const tokenContract = new ethers.Contract(
addresses.token,
@ -24,33 +37,197 @@ const connectProvider = async () => {
signer
);
const walletAddress = await provider.send("eth_requestAccounts", []);
const balance = await tokenContract.balanceOf(walletAddress[0]);
for (let i = 0; i < wallets.length; i++) {
const tx = await tokenContract.transfer(
wallets[i],
ethers.utils.parseEther("4000000.0")
);
await tx.wait();
updateWalletStatus();
}
};
etherStore.setWalletAddress(ethers.utils.getAddress(walletAddress[0]));
etherStore.setBalance(String(balance));
// get all wallet transactions
const listAllTransactionByWalletAddress = async (
walletAddress: string
): Promise<any[] | undefined> => {
const provider = getProvider();
if (!provider) return;
const p2pEvents = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterDeposits = p2pEvents.filters.DepositAdded(null);
const eventsDeposits = await p2pEvents.queryFilter(filterDeposits);
console.log("Deposits Added: ", eventsDeposits);
const filterDeposits = p2pContract.filters.DepositAdded([walletAddress]);
const eventsDeposits = await p2pContract.queryFilter(filterDeposits);
const filterAddedLocks = p2pContract.filters.LockAdded([walletAddress]);
const eventsAddedLocks = await p2pContract.queryFilter(filterAddedLocks);
const filterReleasedLocks = p2pContract.filters.LockReleased([walletAddress]);
const eventsReleasedLocks = await p2pContract.queryFilter(
filterReleasedLocks
);
return [...eventsDeposits, ...eventsAddedLocks, ...eventsReleasedLocks].sort(
(a, b) => {
return b.blockNumber - a.blockNumber;
}
);
};
// get wallet's deposit transactions
const listDepositTransactionByWalletAddress = async (
walletAddress: string
): Promise<any[] | undefined> => {
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterDeposits = p2pContract.filters.DepositAdded([walletAddress]);
const eventsDeposits = await p2pContract.queryFilter(filterDeposits);
return eventsDeposits.sort((a, b) => {
return b.blockNumber - a.blockNumber;
});
};
// get wallet's lock transactions
const listLockTransactionByWalletAddress = async (
walletAddress: string
): Promise<any[] | undefined> => {
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterAddedLocks = p2pContract.filters.LockAdded([walletAddress]);
const eventsAddedLocks = await p2pContract.queryFilter(filterAddedLocks);
return eventsAddedLocks.sort((a, b) => {
return b.blockNumber - a.blockNumber;
});
};
// get wallet's release transactions
const listReleaseTransactionByWalletAddress = async (
walletAddress: string
): Promise<any[] | undefined> => {
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterReleasedLocks = p2pContract.filters.LockReleased([walletAddress]);
const eventsReleasedLocks = await p2pContract.queryFilter(
filterReleasedLocks
);
return eventsReleasedLocks.sort((a, b) => {
return b.blockNumber - a.blockNumber;
});
};
// Update events at store methods
const updateValidDeposits = async () => {
const etherStore = useEtherStore();
const window_ = window as any;
const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null;
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterDeposits = p2pContract.filters.DepositAdded(null);
const eventsDeposits = await p2pContract.queryFilter(filterDeposits);
const depositList = [] as any[];
eventsDeposits.forEach(async (deposit) => {
const mappedDeposit = await mapDeposits(deposit.args?.depositID);
const validDeposit = {
depositID: deposit.args?.depositID,
remaining: formatBigNumber(mappedDeposit.remaining),
seller: mappedDeposit.seller,
pixKey: mappedDeposit.pixTarget,
valid: mappedDeposit.valid,
};
depositList.push(validDeposit);
});
etherStore.setDepositsValidList(depositList);
};
const updateDepositAddedEvents = async () => {
const etherStore = useEtherStore();
const window_ = window as any;
const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null;
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterDeposits = p2pContract.filters.DepositAdded(null);
const eventsDeposits = await p2pContract.queryFilter(filterDeposits);
etherStore.setDepositsAddedList(eventsDeposits);
};
const filterLocks = p2pEvents.filters.LockAdded(null);
const eventsLocks = await p2pEvents.queryFilter(filterLocks);
console.log("Locks Added: ", eventsLocks);
const updateLockAddedEvents = async () => {
const etherStore = useEtherStore();
const window_ = window as any;
const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null;
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterLocks = p2pContract.filters.LockAdded(null);
const eventsLocks = await p2pContract.queryFilter(filterLocks);
etherStore.setLocksAddedList(eventsLocks);
};
const filterExpiredLocks = p2pEvents.filters.LockReturned(null);
const eventsExpiredLocks = await p2pEvents.queryFilter(filterExpiredLocks);
console.log("Expired Locks: ", eventsExpiredLocks);
etherStore.setDepositsExpiredList(eventsExpiredLocks);
const updateLockReleasedEvents = async () => {
const etherStore = useEtherStore();
const window_ = window as any;
const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null;
// (TO DO) Filter valid deposits
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
connection.on("accountsChanged", (accounts: string[]) => {
updateWalletStatus(accounts[0]);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterLocks = p2pContract.filters.LockReleased(null);
const eventsLocks = await p2pContract.queryFilter(filterLocks);
etherStore.setLocksReleasedList(eventsLocks);
};
// Provider methods
const connectProvider = async () => {
const window_ = window as any;
const connection = window_.ethereum;
await updateWalletStatus();
await updateDepositAddedEvents();
await updateLockAddedEvents();
await updateLockReleasedEvents();
await updateValidDeposits();
connection.on("accountsChanged", async () => {
await updateWalletStatus();
});
};
@ -63,49 +240,14 @@ const getProvider = (): ethers.providers.Web3Provider | null => {
return new ethers.providers.Web3Provider(connection);
};
// Wallet methods
// Update wallet state (balance and address)
const updateWalletStatus = async (walletAddress: string) => {
const etherStore = useEtherStore();
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const contract = new ethers.Contract(addresses.token, mockToken.abi, signer);
const balance = await contract.balanceOf(walletAddress);
etherStore.setBalance(String(balance));
etherStore.setWalletAddress(ethers.utils.getAddress(walletAddress));
};
// Split tokens between wallets in wallets.json
const splitTokens = async () => {
const etherStore = useEtherStore();
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const contract = new ethers.Contract(addresses.token, mockToken.abi, signer);
for (let i = 0; i < wallets.length; i++) {
const tx = await contract.transfer(
wallets[i],
ethers.utils.parseEther("4000000.0")
);
await tx.wait();
updateWalletStatus(etherStore.walletAddress);
}
};
// Deposit methods
// Gets value and pix key from user's form to create a deposit in the blockchain
const addDeposit = async (tokenQty = "1000.0", pixKey = "00011122233") => {
const etherStore = useEtherStore();
const addDeposit = async (tokenQty: Number, pixKey: string) => {
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const tokenContract = new ethers.Contract(
addresses.token,
mockToken.abi,
@ -116,44 +258,39 @@ const addDeposit = async (tokenQty = "1000.0", pixKey = "00011122233") => {
// First get the approval
const apprv = await tokenContract.approve(
addresses.p2pix,
ethers.utils.parseEther(tokenQty)
formatEther(String(tokenQty))
);
await apprv.wait();
// Now we make the deposit
const deposit = await p2pContract.deposit(
addresses.token,
ethers.utils.parseEther(tokenQty),
formatEther(String(tokenQty)),
pixKey
);
await deposit.wait();
updateWalletStatus(etherStore.walletAddress);
const p2pEvents = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filter = p2pEvents.filters.DepositAdded(null);
const events = await p2pEvents.queryFilter(filter);
etherStore.setDepositsAddedList(events);
await updateWalletStatus();
await updateDepositAddedEvents();
await updateValidDeposits();
};
// Get specific deposit data by its ID
const mapDeposits = async (depositId: BigNumber) => {
const mapDeposits = async (depositId: BigNumber): Promise<any> => {
const provider = getProvider();
if (!provider) return;
const signer = provider.getSigner();
const contract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const deposit = await contract.mapDeposits(depositId.toNumber());
const deposit = await contract.mapDeposits(depositId);
console.log(deposit);
return deposit;
};
// Lock methods
// Gets value from user's form to create a lock in the blockchain
const addLock = async (depositId: Number, amount: Number) => {
const addLock = async (depositId: BigNumber, amount: Number) => {
const etherStore = useEtherStore();
const provider = getProvider();
@ -162,18 +299,23 @@ const addLock = async (depositId: Number, amount: Number) => {
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
// Make lock
await p2pContract.lock(
depositId,
etherStore.walletAddress,
ethers.constants.AddressZero,
const oldEventsLen = etherStore.locksAddedList.length;
const lock = await p2pContract.lock(
depositId, // BigNumber
etherStore.walletAddress, // String "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" (Example)
ethers.constants.AddressZero, // String "0x0000000000000000000000000000000000000000"
0,
ethers.utils.parseEther(amount.toString()),
formatEther(String(amount)), // BigNumber
[]
);
lock.wait();
const filterLocks = p2pContract.filters.LockAdded(null);
const eventsLocks = await p2pContract.queryFilter(filterLocks);
etherStore.setLocksAddedList(eventsLocks);
while (etherStore.locksAddedList.length === oldEventsLen) {
await updateLockAddedEvents();
await updateValidDeposits();
}
return lock;
};
// Get specific lock data by its ID
@ -186,20 +328,53 @@ const mapLocks = async (lockId: string) => {
const contract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const lock = await contract.mapLocks(lockId);
console.log(lock);
return lock;
};
// Releases lock by specific ID and other additional data
// (TO DO)
const releaseLock = async () => {
return;
const releaseLock = async (
pixKey: string,
amount: Number,
e2eId: string,
lockId: string
) => {
const provider = getProvider();
if (!provider) return;
const mockBacenSigner = new ethers.Wallet(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
);
const messageToSign = ethers.utils.solidityKeccak256(
["string", "uint256", "uint256"],
[pixKey, formatEther(String(amount)), formatEther(e2eId)]
);
const messageHashBytes = ethers.utils.arrayify(messageToSign);
const flatSig = await mockBacenSigner.signMessage(messageHashBytes);
const sig = ethers.utils.splitSignature(flatSig);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const release = await p2pContract.release(
lockId,
formatEther(e2eId),
sig.r,
sig.s,
sig.v
);
release.wait();
await updateLockReleasedEvents();
await updateValidDeposits();
return release;
};
// Formatting methods
const formatEther = (balance: string) => {
const formatted = ethers.utils.formatEther(balance);
return formatted;
const formatEther = (num: string) => {
const formattedNum = ethers.utils.parseEther(num);
return formattedNum;
};
const formatBigNumber = (num: BigNumber) => {
@ -210,11 +385,18 @@ const formatBigNumber = (num: BigNumber) => {
export default {
connectProvider,
formatEther,
updateWalletStatus,
splitTokens,
listAllTransactionByWalletAddress,
listReleaseTransactionByWalletAddress,
listDepositTransactionByWalletAddress,
listLockTransactionByWalletAddress,
addDeposit,
mapDeposits,
formatBigNumber,
addLock,
mapLocks,
releaseLock,
updateLockAddedEvents,
updateValidDeposits,
};

View File

@ -270,6 +270,25 @@
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_addr",
"type": "address"
}
],
"name": "_castAddrToKey",
"outputs": [
{
"internalType": "uint256",
"name": "_key",
"type": "uint256"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{

View File

@ -1,65 +1,88 @@
<script setup lang="ts">
import SearchComponent from "../components/SearchComponent.vue";
import ValidationComponent from "../components/ValidationComponent.vue";
import ValidationComponent from "../components/LoadingComponent.vue";
import ListComponent from "@/components/ListComponent.vue";
import blockchain from "../utils/blockchain";
import { ref } from "vue";
// (TO DO) Tirar isso tudo daqui
import p2pix from "../utils/smart_contract_files/P2PIX.json";
import addresses from "../utils/smart_contract_files/localhost.json";
import { useEtherStore } from "@/store/ether";
import { ethers } from "ethers";
import QrCodeComponent from "../components/QrCodeComponent.vue";
import { storeToRefs } from "pinia";
enum Step {
Search,
Buy,
List,
}
// States
const etherStore = useEtherStore();
const { loadingLock } = storeToRefs(etherStore);
const { loadingLock, walletAddress, locksAddedList } = storeToRefs(etherStore);
const flowStep = ref<Step>(Step.Search);
const pixTarget = ref<string>("");
const tokens = ref<number>();
const tokenAmount = ref<number>();
const lockTransactionHash = ref<string>("");
const lockId = ref<string>("");
const loadingRelease = ref<Boolean>(false);
const lastWalletReleaseTransactions = ref<any[] | undefined>([]);
const confirmBuyClick = async ({ selectedDeposit, tokenValue }: any) => {
// finish buy screen
console.log(selectedDeposit);
let depositDetail;
const depositId = selectedDeposit["args"]["depositID"];
await blockchain
.mapDeposits(depositId)
.then((deposit) => (depositDetail = deposit));
tokens.value = tokenValue;
pixTarget.value = depositDetail?.pixTarget;
const depositDetail = selectedDeposit;
const depositId = selectedDeposit.depositID;
pixTarget.value = selectedDeposit.pixKey;
tokenAmount.value = tokenValue;
// depositId is BigNumber type object
tokenAmount.value = tokenValue;
pixTarget.value = String(depositDetail?.pixTarget);
// Makes lock with deposit ID and the Amount
if (depositDetail) {
flowStep.value = Step.Buy;
etherStore.setLoadingLock(true);
await blockchain.addLock(depositId, tokenValue).catch(() => {
await blockchain
.addLock(depositId, tokenValue)
.then((lock) => {
lockTransactionHash.value = lock.hash;
})
.catch(() => {
flowStep.value = Step.Search;
});
// (TO DO) Tirar isso daqui
const window_ = window as any;
const connection = window_.ethereum;
let provider: ethers.providers.Web3Provider | null = null;
if (!connection) return;
provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const p2pContract = new ethers.Contract(addresses.p2pix, p2pix.abi, signer);
const filterLocks = p2pContract.filters.LockAdded(null);
const eventsLocks = await p2pContract.queryFilter(filterLocks);
etherStore.setLocksAddedList(eventsLocks);
etherStore.setLoadingLock(false);
}
};
// Data to QRCode
// Chave Pix = depositDetail.pixTarget
// Valor = tokenValue
const releaseTransaction = async ({ e2eId }: any) => {
flowStep.value = Step.List;
loadingRelease.value = true;
const findLock = locksAddedList.value.find((element) => {
if (element.transactionHash === lockTransactionHash.value) {
lockId.value = element.args.lockID;
return true;
}
return false;
});
if (findLock && tokenAmount.value) {
const release = await blockchain.releaseLock(
pixTarget.value,
tokenAmount.value,
e2eId,
lockId.value
);
release.wait();
lastWalletReleaseTransactions.value =
await blockchain.listReleaseTransactionByWalletAddress(
walletAddress.value.toLowerCase()
);
await blockchain.updateWalletStatus();
loadingRelease.value = false;
}
};
</script>
@ -72,10 +95,26 @@ const confirmBuyClick = async ({ selectedDeposit, tokenValue }: any) => {
<div v-if="flowStep == Step.Buy">
<QrCodeComponent
:pixTarget="pixTarget"
:tokenValue="tokens"
:tokenValue="tokenAmount"
@pix-validated="releaseTransaction"
v-if="!loadingLock"
/>
<ValidationComponent v-if="loadingLock" />
<ValidationComponent
v-if="loadingLock"
:message="'A transação está sendo enviada para a rede'"
/>
</div>
<div v-if="flowStep == Step.List">
<ListComponent
v-if="!loadingRelease"
:last-wallet-release-transactions="lastWalletReleaseTransactions"
:tokenAmount="tokenAmount"
@make-another-transaction="flowStep = Step.Search"
/>
<ValidationComponent
v-if="loadingRelease"
:message="'A transação está sendo enviada para a rede. Em breve os tokens serão depositados em sua carteira.'"
/>
</div>
</template>

98
src/views/ListView.vue Normal file
View File

@ -0,0 +1,98 @@
<script setup lang="ts">
import CustomButton from "@/components/CustomButton.vue";
</script>
<template>
<div class="page">
<div class="text-container">
<span class="text font-extrabold text-5xl max-w-[50rem]"
>Os tokens foram transferidos <br />
para a sua carteira!
</span>
</div>
<div class="blur-container">
<div
class="flex flex-col w-full bg-white px-10 py-5 rounded-lg border-y-10"
>
<div>
<p>Tokens recebidos</p>
<p class="text-2xl text-gray-900">100 BRZ</p>
</div>
<div class="my-5">
<p>
<b>Não encontrou os tokens? </b>Clique no botão abaixo para <br />
cadastrar o BRZ em sua carteira.
</p>
</div>
<CustomButton
:text="'Cadastrar token na carteira'"
@buttonClicked="() => {}"
/>
</div>
</div>
<div class="blur-container-row">
<button
type="button"
class="border-amber-500 border-2 rounded default-button text-white p-2 px-50 w-full"
@click="() => {}"
>
Fazer nova transação
</button>
<button
type="button"
class="border-amber-500 border-2 rounded default-button text-white p-2"
@click="() => {}"
>
Desconectar
</button>
</div>
<div class="text-container mt-10">
<span class="text font-extrabold text-3xl max-w-[50rem]"
>Últimas transações
</span>
</div>
<div class="blur-container">
<div class="flex flex-row justify-between w-full bg-white p-5 rounded-lg">
<p>100 BRZ</p>
<p>20 out 2022</p>
<p>Etherscan</p>
</div>
<div class="flex flex-row justify-between w-full bg-white p-5 rounded-lg">
<p>100 BRZ</p>
<p>20 out 2022</p>
<p>Etherscan</p>
</div>
<p class="text-white mt-2 cursor-pointer">Carregar mais</p>
</div>
</div>
</template>
<style scoped>
.page {
@apply flex flex-col items-center justify-center w-full mt-16;
}
.text-container {
@apply flex flex-col items-center justify-center gap-4;
}
.text {
@apply text-gray-800 text-center;
}
.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;
}
.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;
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
}
</style>

View File

@ -7,6 +7,7 @@ import blockchain from "../utils/blockchain";
// Blockchain Data
const etherStore = useEtherStore();
const { depositsValidList } = storeToRefs(etherStore);
const { depositsAddedList } = storeToRefs(etherStore);
const { locksAddedList } = storeToRefs(etherStore);
@ -15,7 +16,7 @@ const depositValue = ref<Number>();
const depositPixKey = ref<string>("");
// Split tokens between wallets in wallets.json
const splitTokens = () => {
const splitTokens = async () => {
blockchain.splitTokens();
};
@ -35,23 +36,20 @@ const formatWalletAddress = (wallet: string): string => {
// Gets value and pix key from user's form to create a deposit in the blockchain
const mockDeposit = () => {
if (!depositValue.value || !depositPixKey.value) return;
blockchain.addDeposit(depositValue.value.toString(), depositPixKey.value);
blockchain.addDeposit(depositValue.value, depositPixKey.value);
};
// Get specific deposit data by its ID
const mapDeposit = (depositId: BigNumber) => {
blockchain.mapDeposits(depositId);
const deposit = blockchain.mapDeposits(depositId);
return deposit;
};
// Lock methods
// (TO DO) Releases lock by specific ID and other additional data
const releaseLock = () => {
blockchain.releaseLock();
};
// Get specific lock data by its ID
const mapLock = (lockId: string) => {
blockchain.mapLocks(lockId);
const lock = blockchain.mapLocks(lockId);
return lock;
};
</script>
@ -81,10 +79,6 @@ const mapLock = (lockId: string) => {
<button type="button" class="default-button" @click="splitTokens()">
Dividir tokens
</button>
<button type="button" class="default-button" @click="releaseLock()">
Release Lock
</button>
</div>
<ul class="flex flex-col justify-center items-center gap-4">
@ -95,7 +89,7 @@ const mapLock = (lockId: string) => {
@click="mapDeposit(deposit.args.depositID)"
>
Seller:<br />{{ formatWalletAddress(deposit.args.seller) }}<br />
MRBZ: {{ blockchain.formatEther(deposit.args.amount) }}
MRBZ: {{ blockchain.formatBigNumber(deposit.args.amount) }}
</li>
</ul>
<ul class="flex flex-col justify-center items-center gap-4">
@ -106,7 +100,18 @@ const mapLock = (lockId: string) => {
@click="mapLock(lock.args.lockID)"
>
Buyer:<br />{{ formatWalletAddress(lock.args.buyer) }}<br />
MRBZ: {{ blockchain.formatEther(lock.args.amount) }}
MRBZ: {{ blockchain.formatBigNumber(lock.args.amount) }}
</li>
</ul>
<ul class="flex flex-col justify-center items-center gap-4">
<li
class="text-gray-900 font-semibold text-lg cursor-pointer border-2 border-amber-400 p-2 rounded-md bg-amber-200"
v-for="valid in depositsValidList"
:key="valid.depositID"
@click="mapDeposit(valid.depositID)"
>
Buyer:<br />{{ formatWalletAddress(valid.seller) }}<br />
MRBZ: {{ valid.remaining }}
</li>
</ul>
</div>

60
src/views/SellerView.vue Normal file
View File

@ -0,0 +1,60 @@
<script setup lang="ts">
import WantSellComponent from "../components/SellerSteps/WantSellComponent.vue";
import SendNetwork from "../components/SellerSteps/SendNetwork.vue";
import ValidationComponent from "../components/LoadingComponent.vue";
import { ref } from "vue";
import router from "@/router";
enum Step {
Search,
Sell,
Network,
}
const flowStep = ref<Step>(Step.Sell);
const loading = ref<boolean>(false);
const walletConnect = async () => {
flowStep.value = Step.Sell;
};
const approveTokens = async () => {
loading.value = true;
setTimeout(() => {
loading.value = false;
flowStep.value = Step.Network;
}, 2000);
};
const sendNetwork = async () => {
loading.value = true;
setTimeout(() => {
loading.value = false;
router.push("/");
}, 2000);
};
</script>
<template>
<!-- <SellerSearchComponent
v-if="flowStep == Step.Search"
@token-buy="walletConnect"
/> -->
<div v-if="flowStep == Step.Sell">
<WantSellComponent v-if="!loading" @approve-tokens="approveTokens" />
<ValidationComponent
v-if="loading"
:message="'A transação está sendo enviada para a rede.'"
/>
</div>
<div v-if="flowStep == Step.Network">
<SendNetwork v-if="!loading" @send-network="sendNetwork" />
<ValidationComponent
v-if="loading"
:message="'A transação está sendo enviada para a rede.'"
/>
</div>
</template>
<style scoped></style>