Merge branch 'develop' into create_menu
This commit is contained in:
commit
927aaf79ad
20 files changed
+1229
-201
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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 }}
|
||||
+25
-27
@@ -1,36 +1,34 @@
|
||||
<svg width="1440" height="1000" viewBox="0 0 1440 1000" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g clip-path="url(#clip0_287_693)">
|
||||
<rect width="1440" height="1024" fill="#1F201F"/>
|
||||
<g opacity="0.95" filter="url(#filter0_f_287_693)">
|
||||
<path d="M-201.654 473.827C-222.477 444.181 -135.601 330.211 -89.5597 276.932C-49.4017 218.853 43.3929 96.4789 93.3068 71.617C155.699 40.5396 210.838 35.3775 317.517 -11.2546C424.196 -57.8866 502.694 -55.2624 735.23 -98.2918C967.765 -141.321 845.508 -108.616 1004.93 -17.1029C1164.34 74.4104 1065.11 95.9907 1062.91 240.162C1060.7 384.333 1011.31 298.816 950.963 359.294C890.614 419.773 745.865 102.857 659.906 180.422C573.948 257.987 603.99 222.804 631.303 515.382C719.043 538.676 669.559 513.737 786.064 531.038C902.568 548.34 841.342 543.924 898.86 627.747C956.378 711.57 920.305 760.663 763.535 930.713C606.764 1100.76 678.128 877.105 556.37 836.495C434.612 795.884 469.116 795.022 364.298 774.382C259.479 753.742 273.152 715.643 190.459 810.604C107.766 905.565 136.335 858.035 9.50706 890.789C-117.321 923.542 -42.076 853.633 -82.654 789.781C-123.232 725.928 -87.7013 671.525 -128.961 584.314C-170.22 497.104 -175.626 510.884 -201.654 473.827Z" fill="#34D399"/>
|
||||
<path d="M639.724 600.298C626.679 563.102 622.703 489.667 646.882 420.45L639.842 401.512C671.313 366.898 740.22 289.289 764.074 255.768L802.907 201.199C816.776 181.71 839.659 149.554 1132.23 63.0568C1212.05 64.0728 1182.68 62.6322 1300.64 88.0195C1418.6 113.407 1363.12 119.825 1461.61 193.924C1560.1 268.023 1525.73 259.72 1577.35 355.912C1628.96 452.104 1601.61 399.772 1588.77 495.766C1575.93 591.759 1566.81 575.743 1508.37 665.34C1449.93 754.937 1434.08 734.495 1384.55 782.741C1335.02 830.986 1336.46 807.61 1287.13 841.684C1237.81 875.759 1225.38 871.872 1162.59 897.092C1099.81 922.313 1108.65 908.817 1002.18 923.89C895.704 938.964 940.587 883.368 856.111 875.001C771.635 866.635 787.79 830.052 718.951 784.761C650.113 739.471 687.961 736.474 673.514 707.655C659.066 678.835 652.77 637.495 639.724 600.298Z" fill="#60A5FA"/>
|
||||
<svg width="1440" height="1024" viewBox="0 0 1440 1024" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g clip-path="url(#clip0_847_732)">
|
||||
<rect width="1440" height="1024" fill="#111827"/>
|
||||
<rect width="1440" height="1024" fill="url(#pattern0)" style="mix-blend-mode:overlay"/>
|
||||
<g opacity="0.95" filter="url(#filter0_f_847_732)">
|
||||
<path d="M1367.83 552.44C1379.11 529.54 1262.11 485.261 1202.2 465.985C1146.53 442.342 1021.37 394.67 966.096 393.127C897.008 391.198 842.513 402.615 726.299 403.143C610.086 403.671 535.439 425.792 299.367 461.43C63.2953 497.068 190.378 484.263 64.1408 579.89C-62.0961 675.517 39.591 662.202 84.1295 746.443C128.668 830.684 150.957 767.426 226.733 787.188C302.508 806.95 239.996 767.481 354.257 773.476C375.949 774.614 401.683 767.919 401.683 767.919C401.683 767.919 512.832 794.344 405.989 835.062C299.146 875.779 466.967 891.673 436.369 956.064C405.771 1020.46 392.204 1020.91 592.857 1079.86C793.511 1138.81 751.424 1048.76 856.456 992.952C961.488 937.144 866.361 996.221 960.994 956.602C1055.63 916.984 982.798 819.165 1090.19 853.356C1197.58 887.548 1156.14 867.074 1287.63 853.099C1419.12 839.124 1326.26 817.718 1346.46 769.516C1366.66 721.313 1316.51 698.62 1330.49 636.497C1344.47 574.374 1353.72 581.064 1367.83 552.44Z" fill="#059669"/>
|
||||
<path d="M1235.57 657.249C1203.31 684.536 1121.94 723.971 1022.6 742.63L1006.49 756.787C941.094 753.271 795.807 746.487 737.846 747.473L643.49 749.078C609.792 749.651 554.189 750.597 217.256 600.01C153.678 546.586 175.842 566.777 109.411 475.865C42.9808 384.952 95.3741 418.513 100.844 316.093C106.315 213.674 124.624 240.615 193.565 158.199C262.507 75.7822 224.41 120.137 345.399 80.5427C466.387 40.9481 455.336 55.0195 605.944 48.8584C756.551 42.6973 745.859 63.4473 841.608 72.1027C937.357 80.7582 909.264 91.52 988.522 107.141C1067.78 122.761 1073.39 132.95 1153.36 161.928C1233.33 190.905 1210.61 191.806 1314.34 254.831C1418.06 317.856 1317.62 315.966 1376.5 376.154C1435.38 436.343 1380.13 443.967 1383.8 512.294C1387.46 580.62 1353.31 557.034 1331.83 581.052C1310.35 605.071 1267.84 629.962 1235.57 657.249Z" fill="#60A5FA"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:color-burn" opacity="0.4" filter="url(#filter1_f_287_693)">
|
||||
<path d="M626.141 -22.8748C644.643 -46.9528 690.436 -81.2177 745.481 -96.498L754.731 -109C790.502 -104.833 870 -96.498 901.824 -96.498H953.63C972.133 -96.498 1002.66 -96.498 1183.06 44.2659C1216.36 93.348 1204.8 74.8264 1238.56 157.71C1272.33 240.594 1244.58 209.571 1238.56 301.715C1232.55 393.86 1223.3 369.319 1183.06 442.479C1142.82 515.639 1165.02 476.281 1097.49 510.083C1029.95 543.885 1036.43 531.383 953.63 534.624C870.833 537.865 877.309 519.344 825.04 510.083C772.771 500.822 788.498 491.561 745.481 476.281C702.463 461.001 699.687 451.74 656.67 424.421C613.652 397.101 626.141 396.638 571.097 338.296C516.053 279.953 571.097 283.194 540.568 228.092C510.04 172.991 540.568 166.971 540.568 105.387C540.568 43.8028 558.608 65.5656 571.097 44.2659C583.586 22.9661 607.639 1.20325 626.141 -22.8748Z" fill="#93C5FD"/>
|
||||
<path d="M-2.07087 334.224C-12.8709 315.424 73.0958 262.391 117.429 238.224C158.096 210.724 250.029 153.724 292.429 145.724C345.429 135.724 388.429 139.224 477.929 125.724C567.429 112.224 626.929 122.724 811.929 125.724C996.929 128.724 897.929 132.724 1003.93 201.724C1109.93 270.724 1030.43 271.224 1003.93 350.724C977.429 430.224 954.429 377.224 897.929 403.724C841.429 430.224 785.429 238.224 706.429 271.224C627.429 304.224 656.429 288.224 626.929 453.224C689.929 476.224 656.429 456.724 742.429 479.724C828.429 502.724 782.429 493.224 811.929 546.224C841.429 599.224 805.429 622.224 656.429 698.224C507.429 774.224 600.429 658.724 514.429 622.224C428.429 585.724 454.929 589.224 378.429 565.724C301.929 542.224 318.929 522.724 239.429 565.724C159.929 608.724 189.929 585.724 87.4292 589.224C-15.0708 592.724 54.4292 562.724 34.4292 522.724C14.4292 482.724 50.9292 456.724 34.4292 403.724C17.9292 350.724 11.4291 357.724 -2.07087 334.224Z" fill="#34D399"/>
|
||||
<path d="M139.079 -13.5933C157.013 -33.1151 272.628 60.3273 328.195 109.489L352.034 127.701C402.248 156.414 507.751 223.506 528.049 262.167C553.421 310.494 551.898 301.78 571.911 379.361C591.924 456.941 634.429 422.717 700.385 473.104L865.671 599.374C947.123 661.599 939.887 676.836 952.73 807.455C965.572 938.074 851.31 809.255 759.13 738.835C666.951 668.415 732.907 718.802 636.339 703.545C539.77 688.288 576.259 678.411 410.067 564.033C243.875 449.654 283.902 412.908 246.583 347.274C209.263 281.641 238.831 308.004 201.62 275.173C164.41 242.341 137.172 201.398 84.6605 123.529C32.149 45.6607 116.661 10.8088 139.079 -13.5933Z" fill="#FB923C"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.5">
|
||||
<rect y="-11" width="1440" height="1028" fill="url(#pattern0)"/>
|
||||
<g style="mix-blend-mode:color-burn" opacity="0.4" filter="url(#filter1_f_847_732)">
|
||||
<path d="M238.125 432.859C214.047 414.357 179.782 368.564 164.502 313.519L152 304.269C156.167 268.498 164.502 189 164.502 157.176L164.502 105.37C164.502 86.8673 164.502 56.3386 305.266 -124.058C354.348 -157.362 335.826 -145.798 418.71 -179.565C501.594 -213.331 470.571 -185.578 562.715 -179.565C654.86 -173.552 630.319 -164.3 703.479 -124.058C776.639 -83.8157 737.281 -106.018 771.083 -38.4853C804.885 29.0479 792.383 22.5721 795.624 105.37C798.865 188.167 780.344 181.691 771.083 233.96C761.822 286.229 752.561 270.502 737.281 313.519C722.001 356.537 712.74 359.313 685.421 402.33C658.101 445.348 657.638 432.859 599.296 487.903C540.953 542.947 544.194 487.903 489.092 518.432C433.991 548.96 427.971 518.432 366.387 518.432C304.803 518.432 326.566 500.392 305.266 487.903C283.966 475.414 262.203 451.361 238.125 432.859Z" fill="#93C5FD"/>
|
||||
<path d="M1004.22 1306.57C985.424 1317.37 932.391 1231.4 908.224 1187.07C880.724 1146.4 823.724 1054.47 815.724 1012.07C805.724 959.071 809.224 916.071 795.724 826.571C782.224 737.071 792.724 677.571 795.724 492.571C798.724 307.571 802.724 406.571 871.724 300.571C940.724 194.571 941.224 274.071 1020.72 300.571C1100.22 327.071 1047.22 350.071 1073.72 406.571C1100.22 463.071 908.224 519.071 941.224 598.071C974.224 677.071 958.224 648.071 1123.22 677.571C1146.22 614.571 1126.72 648.071 1149.72 562.071C1172.72 476.071 1163.22 522.071 1216.22 492.571C1269.22 463.071 1292.22 499.071 1368.22 648.071C1444.22 797.071 1328.72 704.071 1292.22 790.071C1255.72 876.071 1259.22 849.571 1235.72 926.071C1212.22 1002.57 1192.72 985.571 1235.72 1065.07C1278.72 1144.57 1255.72 1114.57 1259.22 1217.07C1262.72 1319.57 1232.72 1250.07 1192.72 1270.07C1152.72 1290.07 1126.72 1253.57 1073.72 1270.07C1020.72 1286.57 1027.72 1293.07 1004.22 1306.57Z" fill="#34D399"/>
|
||||
<path d="M130.673 446.681C131.953 420.203 280.592 417.975 354.751 420.17L384.725 418.9C441.682 408.812 565.682 392.815 606.026 409.521C656.455 430.405 649.707 424.685 714.747 471.474C779.786 518.262 790.53 464.759 873.456 461.245L1081.27 452.438C1183.68 448.098 1187.87 464.435 1281.36 556.559C1374.84 648.684 1204.6 622.869 1088.7 627.78C972.804 632.692 1055.73 629.178 971.776 679.277C887.822 729.377 909.531 698.43 708.635 716.953C507.739 735.475 514.965 681.621 444.278 655.09C373.592 628.559 413.183 629.884 363.579 628.483C313.975 627.082 266.84 613.065 176.649 586.86C86.4589 560.656 129.073 479.779 130.673 446.681Z" fill="#FB923C"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_287_693" x="-494.823" y="-407.035" width="2392.4" height="1690.74" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_287_693"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_287_693" x="-293.001" y="-399" width="1838" height="1552.6" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_287_693"/>
|
||||
</filter>
|
||||
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
|
||||
<use xlink:href="#image0_287_693" transform="translate(0 0.0100778) scale(0.0005 0.000700389)"/>
|
||||
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="0.355556" height="0.5">
|
||||
<use xlink:href="#image0_847_732" transform="scale(0.000347222 0.000488281)"/>
|
||||
</pattern>
|
||||
<clipPath id="clip0_287_693">
|
||||
<filter id="filter0_f_847_732" x="-286.884" y="-242.267" width="1980.68" height="1631.39" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_847_732"/>
|
||||
</filter>
|
||||
<filter id="filter1_f_847_732" x="-170.772" y="-486" width="1854.36" height="2083.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="145" result="effect1_foregroundBlur_847_732"/>
|
||||
</filter>
|
||||
<clipPath id="clip0_847_732">
|
||||
<rect width="1440" height="1024" fill="white"/>
|
||||
</clipPath>
|
||||
<image id="image0_287_693" width="2000" height="1399" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB9AAAAV3CAIAAACG3GNRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAxRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDExNi4xNjQ3NjYsIDIwMjEvMDIvMTktMjM6MTA6MDcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjU0OTE2OTdBQzgxRjExRUNBMTk3QjczNUFCQkJDREVGIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjU0OTE2OTc5QzgxRjExRUNBMTk3QjczNUFCQkJDREVGIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyMDIwIE1hY2ludG9zaCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSIyNEE5MThCRjQwQzEwNDNGNjdBMDQ0OEFFMDlFRjVCNSIgc3RSZWY6ZG9jdW1lbnRJRD0iMjRBOTE4QkY0MEMxMDQzRjY3QTA0NDhBRTA5RUY1QjUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz69AeqQAC8D+ElEQVR42kzdWZOeVdX/cTEOjzOOqDggIiTp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 truncated
|
||||
<image id="image0_847_732" width="1024" height="1024" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABAAAAAQACAYAAAB/HSuDAAAAAXNSR0IArs4c6QAAIABJREFUeF7s3WW8Nd2yHfQ5cHfXECB4cHe9uAd3d4IEDQRIcHcJ7hLcnQAJ7u7u7s7Ib1f3/5zZnf2859wP957zYb5f1rufvfZa3TVr1qweY1RV2v6j6/rvL7lff5/79Te7X3/Z+/VfuV9/jI/XJP/Ax2vb3+T+9//rfv0r7t//ePfvf6/75z/j/vkPvd/3292vf+r9+z/r/v0fd//7P3K//jz36199v/7a9+uvcb/+W/frz3G//t/36w+4X3/R+/P/gvvzf8L73//A+/U3vV+/x/2+3D/PS9t/7P75R7tff/z79U+6X//V++/+2fv9P//987/w+pyf5f73f/d+n+v9++/3/dv36y90v+8nuN/3S9z//nPdr+wx97XW+svu13/5fv0T7tf/4361fvP7JL/A/bl/6f3zb3P//GffP//u98/zPUlm3dv+WPfnWYe/+/7557xff+z71Xp8z/vnf32/r7XW/3D//APv1z/mfv2l7tdf6379l+7v/4nv7/8j7n//7e/Xv/J+/fXu1//2fv98Ttsf5XVdP9X98+9wv/7g+5V9/4377/+5++9/vvv3f+79+pffr9/3fv1d7tff8X79H++//93uv/d+/jT7K8k/dL9/XtqO36y1fvr79S+6X//P+/Vvvv/OOrieH3L/nv3///vnv/N+/QXv11/xfv1B9+v/dr/+0/er9fpP7p9/q/v1x71f/6P7dfxxrfVz368/zv36G9yvP/V9nRM/2vr7P/3+vXWf9Uwy69DW9f1M9/t+/fvV/vf57PH73r8f/11rzT5LMtfd9s9/3e/3u3/mL7/C/f6JM21nnyQZ/23769w//633z/zRfv1V7s/7/V+vf9X9s3j3q91/b91/2/tnce+3uL9nrqftxKe11p93v/6U9+9nn7X9ne5/t26/+ste4ydrrT/g/jtxbv6x7R9///7fv1/tO/uK//yG9+//3vtVPPuN75993h99//w/36+9X/+++/v/xc/en2Tif9vvc//+H75f+f+cK2stcfA/eH3OX3j//Dfdr/Nzkp/m/lx+xz72CT/8p+6/sw//hvvn/+X+HOv2s93/Puu51vpT7lf78Xu/rkscH/uvtf7E+3X8NcnE37a/9/2z65m3tf0Z7/eL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 truncated
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 MiB After Width: | Height: | Size: 744 KiB |
@@ -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 |
@@ -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 já 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 há 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 há 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>
|
||||
@@ -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>
|
||||
@@ -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 há 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>
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import router from "@/router";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useEtherStore } from "../store/ether";
|
||||
import { ref } from "vue";
|
||||
@@ -27,11 +28,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);
|
||||
};
|
||||
|
||||
const disconnectUser = () => {
|
||||
@@ -55,7 +54,13 @@ const disconnectUser = () => {
|
||||
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"
|
||||
|
||||
@@ -3,6 +3,7 @@ import HomeView from "../views/HomeView.vue";
|
||||
import MockView from "../views/MockView.vue";
|
||||
import BidHistoryView from "../views/BidHistoryView.vue";
|
||||
import ManageBidsView from "../views/ManageBidsView.vue";
|
||||
import SellerView from "@/views/SellerView.vue";
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
@@ -12,6 +13,11 @@ const router = createRouter({
|
||||
name: "home",
|
||||
component: HomeView,
|
||||
},
|
||||
{
|
||||
path: "/seller",
|
||||
name: "seller",
|
||||
component: SellerView,
|
||||
},
|
||||
{
|
||||
path: "/mock",
|
||||
name: "mock",
|
||||
|
||||
@@ -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;
|
||||
},
|
||||
},
|
||||
});
|
||||
+273
-91
@@ -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,
|
||||
};
|
||||
@@ -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": [
|
||||
{
|
||||
|
||||
+73
-34
@@ -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(() => {
|
||||
flowStep.value = Step.Search;
|
||||
});
|
||||
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>
|
||||
|
||||
|
||||
@@ -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 já 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>
|
||||
+20
-15
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user