24 Commits
Author SHA1 Message Date
EmberSpirit 7d1e7dcbf5 contract update 2023-10-24 06:31:01 +02:00
EmberSpirit cc3fb88d1e replace static 18n 2023-10-23 22:09:42 +02:00
EmberSpirit fcf6133a47 contract update 2023-10-23 22:00:09 +02:00
EmberSpirit 32db2d291c update bloodchart compact number 2023-10-23 21:58:54 +02:00
EmberSpirit 1b799b8825 Merge branch 'fix/simplifyUniswap' into development 2023-10-23 21:40:07 +02:00
EmberSpirit 99ff2cb166 merge pull request 2023-10-23 21:39:39 +02:00
EmberSpirit 6e58bc6319 update m issues + e frontend improvements 2023-10-23 21:35:38 +02:00
butterscotch 74dd5b7e0a sacrifice.js getRewards fixes 2023-10-23 20:45:24 +03:00
butterscotch bc3b7eac67 simplified uniswap.js 2023-10-23 01:01:34 +03:00
EmberSpirit 44df04cc23 fix issues e + new contracts 2023-10-22 21:37:15 +02:00
EmberSpirit bf76e55fb5 update m issues + digit change numbers 2023-10-22 17:14:00 +02:00
EmberSpirit fa4fa54033 bloodchart crown fix 2023-10-19 20:47:32 +02:00
EmberSpirit 167ad941bc update m issues + e issues 2023-10-19 20:30:27 +02:00
EmberSpirit cfaf527b95 bloodchart resize 2023-10-19 11:46:43 +02:00
EmberSpirit f45128ceb9 update visual fixes 2023-10-18 23:26:29 +02:00
EmberSpirit 32ababbb39 update bigint + smaller style issues fixes 2023-10-17 22:19:52 +02:00
EmberSpirit fedcd0314d Merge branch 'feat/sacrificeChoice' into development 2023-10-17 18:18:03 +02:00
EmberSpirit 9eabba9c11 merged pull request 2023-10-17 18:17:18 +02:00
EmberSpirit d25ef5ad63 bigint umpdate 2023-10-17 18:06:25 +02:00
EmberSpirit d761adef18 fix user not logged in getrewardsFor & badget +/- fix 2023-10-16 17:31:44 +02:00
EmberSpirit 1fb59225e3 bloodsplash component fix 2023-10-16 13:54:24 +02:00
EmberSpirit b3191f493b blood splash 2023-10-16 13:52:19 +02:00
EmberSpirit 35f2f0782f stepper badge update + injected wallet + smaller fixes 2023-10-16 12:07:07 +02:00
EmberSpirit 301c569edc footer gap improve 2023-10-16 09:36:24 +02:00
50 changed files with 4098 additions and 2924 deletions
+212 -4
View File
@@ -20,10 +20,12 @@
"sass": "^1.62.1", "sass": "^1.62.1",
"swiper": "^9.4.1", "swiper": "^9.4.1",
"viem": "^1.4.1", "viem": "^1.4.1",
"vite-svg-loader": "^4.0.0",
"vue": "^3.3.2", "vue": "^3.3.2",
"vue-collapsed": "^1.2.8", "vue-collapsed": "^1.2.8",
"vue-router": "^4.2.0", "vue-router": "^4.2.0",
"vue-toastification": "^2.0.0-rc.5" "vue-toastification": "^2.0.0-rc.5",
"vue3-lottie": "^3.2.0"
}, },
"devDependencies": { "devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
@@ -1533,6 +1535,14 @@
"@stablelib/wipe": "^1.0.1" "@stablelib/wipe": "^1.0.1"
} }
}, },
"node_modules/@trysound/sax": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
"engines": {
"node": ">=10.13.0"
}
},
"node_modules/@types/connect": { "node_modules/@types/connect": {
"version": "3.4.35", "version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@@ -2471,8 +2481,7 @@
"node_modules/boolbase": { "node_modules/boolbase": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
"dev": true
}, },
"node_modules/borsh": { "node_modules/borsh": {
"version": "0.7.0", "version": "0.7.0",
@@ -2711,6 +2720,44 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/css-select": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"dependencies": {
"boolbase": "^1.0.0",
"css-what": "^6.1.0",
"domhandler": "^5.0.2",
"domutils": "^3.0.1",
"nth-check": "^2.0.1"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/css-what": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"engines": {
"node": ">= 6"
},
"funding": {
"url": "https://github.com/sponsors/fb55"
}
},
"node_modules/cssesc": { "node_modules/cssesc": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -2723,6 +2770,36 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/csso": {
"version": "5.0.5",
"resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
"integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
"dependencies": {
"css-tree": "~2.2.0"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/css-tree": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
"integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
"dependencies": {
"mdn-data": "2.0.28",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/csso/node_modules/mdn-data": {
"version": "2.0.28",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
"integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="
},
"node_modules/csstype": { "node_modules/csstype": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
@@ -2799,6 +2876,57 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/duplexify": { "node_modules/duplexify": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz",
@@ -2847,6 +2975,17 @@
"once": "^1.4.0" "once": "^1.4.0"
} }
}, },
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/es6-promise": { "node_modules/es6-promise": {
"version": "4.2.8", "version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
@@ -3941,6 +4080,11 @@
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true "dev": true
}, },
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
},
"node_modules/lodash.isequal": { "node_modules/lodash.isequal": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@@ -3964,6 +4108,11 @@
"loose-envify": "cli.js" "loose-envify": "cli.js"
} }
}, },
"node_modules/lottie-web": {
"version": "5.12.2",
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.12.2.tgz",
"integrity": "sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg=="
},
"node_modules/lru-cache": { "node_modules/lru-cache": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -3984,6 +4133,11 @@
"sourcemap-codec": "^1.4.8" "sourcemap-codec": "^1.4.8"
} }
}, },
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="
},
"node_modules/micro-ftch": { "node_modules/micro-ftch": {
"version": "0.3.1", "version": "0.3.1",
"resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz",
@@ -4103,7 +4257,6 @@
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dev": true,
"dependencies": { "dependencies": {
"boolbase": "^1.0.0" "boolbase": "^1.0.0"
}, },
@@ -4993,6 +5146,37 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/svgo": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz",
"integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==",
"dependencies": {
"@trysound/sax": "0.2.0",
"commander": "^7.2.0",
"css-select": "^5.1.0",
"css-tree": "^2.2.1",
"csso": "^5.0.5",
"picocolors": "^1.0.0"
},
"bin": {
"svgo": "bin/svgo"
},
"engines": {
"node": ">=14.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/svgo"
}
},
"node_modules/svgo/node_modules/commander": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
"engines": {
"node": ">= 10"
}
},
"node_modules/swiper": { "node_modules/swiper": {
"version": "9.4.1", "version": "9.4.1",
"resolved": "https://registry.npmjs.org/swiper/-/swiper-9.4.1.tgz", "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.4.1.tgz",
@@ -5370,6 +5554,15 @@
} }
} }
}, },
"node_modules/vite-svg-loader": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/vite-svg-loader/-/vite-svg-loader-4.0.0.tgz",
"integrity": "sha512-0MMf1yzzSYlV4MGePsLVAOqXsbF5IVxbn4EEzqRnWxTQl8BJg/cfwIzfQNmNQxZp5XXwd4kyRKF1LytuHZTnqA==",
"dependencies": {
"@vue/compiler-sfc": "^3.2.20",
"svgo": "^3.0.2"
}
},
"node_modules/vite/node_modules/@esbuild/android-arm": { "node_modules/vite/node_modules/@esbuild/android-arm": {
"version": "0.18.20", "version": "0.18.20",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz",
@@ -5822,6 +6015,21 @@
"vue": "^3.0.2" "vue": "^3.0.2"
} }
}, },
"node_modules/vue3-lottie": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/vue3-lottie/-/vue3-lottie-3.2.0.tgz",
"integrity": "sha512-PtNXbv7iD4XGmK8CXd71aLWmILIR6P6VzLMDw6ZzmDAeuJZuJ0MdOVnn50LOARgq+cOFJsn/2z+7tZh0F9T9qw==",
"dependencies": {
"lodash-es": "^4.17.21",
"lottie-web": "5.12.2"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"vue": "^3.2"
}
},
"node_modules/web3-eth-abi": { "node_modules/web3-eth-abi": {
"version": "1.10.1", "version": "1.10.1",
"resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.1.tgz", "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.10.1.tgz",
+3 -1
View File
@@ -21,10 +21,12 @@
"sass": "^1.62.1", "sass": "^1.62.1",
"swiper": "^9.4.1", "swiper": "^9.4.1",
"viem": "^1.4.1", "viem": "^1.4.1",
"vite-svg-loader": "^4.0.0",
"vue": "^3.3.2", "vue": "^3.3.2",
"vue-collapsed": "^1.2.8", "vue-collapsed": "^1.2.8",
"vue-router": "^4.2.0", "vue-router": "^4.2.0",
"vue-toastification": "^2.0.0-rc.5" "vue-toastification": "^2.0.0-rc.5",
"vue3-lottie": "^3.2.0"
}, },
"devDependencies": { "devDependencies": {
"@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

+57 -10
View File
@@ -13,11 +13,16 @@ import { useCycleStore } from "@/stores/cycles";
import SlideoutPanel from "./components/SlideoutPanel.vue"; import SlideoutPanel from "./components/SlideoutPanel.vue";
import ConnectWallet from "./components/ConnectWallet.vue"; import ConnectWallet from "./components/ConnectWallet.vue";
import BloodSplash from "./components/BloodSplash.vue";
import { getNetwork, fetchTransaction } from "@wagmi/core"; import { getNetwork, fetchTransaction } from "@wagmi/core";
import profileIcon from "@/assets/img/profile-icon.svg?component";
import cycleIcon from "@/assets/img/cycle-icon.svg?component";
import homeIcon from "@/assets/img/home-icon.svg?component";
const isMobile = ref(false); const isMobile = ref(false);
const showPanel = ref(false); const showPanel = ref(false);
const splashBlood = ref(0);
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
@@ -32,8 +37,14 @@ watch(showPanel, (newValue, oldValue) => {
console.log("document.body", document.body); console.log("document.body", document.body);
if (newValue) { if (newValue) {
document.body.classList.add("sideoutpanel-open"); document.body.classList.add("sideoutpanel-open");
if (isMobile) {
document.body.classList.add("mobile");
}
} else { } else {
document.body.classList.remove("sideoutpanel-open"); document.body.classList.remove("sideoutpanel-open");
if (isMobile) {
document.body.classList.remove("mobile");
}
} }
}); });
@@ -58,6 +69,7 @@ function changeRoute(name) {
} }
provide("isMobile", isMobile); provide("isMobile", isMobile);
provide("showPanel", showPanel); provide("showPanel", showPanel);
provide("splashBlood", splashBlood);
onMounted(async () => { onMounted(async () => {
window.addEventListener("resize", handleWindowSizeChange); window.addEventListener("resize", handleWindowSizeChange);
@@ -76,6 +88,7 @@ onMounted(async () => {
cycleStore.activeCycle = cycleStore.currentCycle; cycleStore.activeCycle = cycleStore.currentCycle;
} }
console.log("cycleStore.activeCycle", cycleStore.activeCycle);
await cycleStore.fillCycle(cycleStore.activeCycle); await cycleStore.fillCycle(cycleStore.activeCycle);
}); });
</script> </script>
@@ -88,9 +101,12 @@ onMounted(async () => {
<div class="main" :class="{ 'no-scroll': showPanel, mobile: isMobile }"> <div class="main" :class="{ 'no-scroll': showPanel, mobile: isMobile }">
<RouterView /> <RouterView />
</div> </div>
<blood-splash :key="splashBlood"></blood-splash>
<div class="footer"> <div class="footer">
<div class="footer-inner"> <div class="footer-inner">
<div class="footer-headline">Join Bloodline</div> <div class="footer-headline" v-if="!isMobile">Join Bloodline</div>
<div class="footer-social-links"> <div class="footer-social-links">
<div class="social-bloodline-badge"> <div class="social-bloodline-badge">
<div class="social-bloodline-badge-icon"> <div class="social-bloodline-badge-icon">
@@ -107,18 +123,29 @@ onMounted(async () => {
<font-awesome-icon icon="fa-brands fa-twitter" /> <font-awesome-icon icon="fa-brands fa-twitter" />
</div> </div>
</div> </div>
<div class="social-bloodline-badge">
<div class="social-bloodline-badge-icon">
<font-awesome-icon icon="fa-solid fa-blog" />
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="mobile-navigation-bar" v-if="isMobile"> <div class="mobile-navigation-bar" v-if="isMobile">
<div @click="changeRoute('home')" :class="{ active: route.name === 'home' }"> <div @click="changeRoute('home')" :class="{ active: route.name === 'home' }">
<font-awesome-icon icon="fa-droplet" /> <!-- <font-awesome-icon icon="fa-droplet" /> -->
<!-- <img src="/assets/img/sacrifice-icon.png" alt="sacrifice-icon" /> -->
<homeIcon />
</div> </div>
<div @click="changeRoute('cycle')" :class="{ active: route.name === 'cycle' }"> <div @click="changeRoute('cycle')" :class="{ active: route.name === 'cycle' }">
<font-awesome-icon icon="fa-moon" /> <!-- <font-awesome-icon icon="fa-moon" /> -->
<!-- <img src="/assets/img/cycle-icon.png" alt="cycle-icon" /> -->
<cycleIcon />
</div> </div>
<div @click="changeRoute('profile')" :class="{ active: route.name === 'profile' }"> <div @click="changeRoute('profile')" :class="{ active: route.name === 'profile' }">
<font-awesome-icon icon="fa-person" /> <!-- <img src="/assets/img/profile-icon.svg " alt="profile-icon" /> -->
<profileIcon />
<!-- <font-awesome-icon icon="fa-person" /> -->
</div> </div>
</div> </div>
</template> </template>
@@ -127,22 +154,30 @@ onMounted(async () => {
.footer .footer
height: auto height: auto
background-color: var(--midnight-black) background-color: #2D2D2D
padding-bottom: 72px
@media (min-width: 992px) @media (min-width: 992px)
background-color: var(--midnight-black)
height: 150px height: 150px
min-height: 150px min-height: 150px
display: flex display: flex
flex-direction: column flex-direction: column
justify-content: center justify-content: center
padding-bottom: unset
margin-top: auto
.footer-inner .footer-inner
padding: 16px 0 24px 0 padding: 24px 0
font-size: 24px font-size: 24px
display: flex display: flex
flex-direction: column flex-direction: column
gap: 8px gap: 16px
align-items: center align-items: center
border-top: 1px solid #000
@media (min-width: 992px) @media (min-width: 992px)
padding: 16px 0 24px 0
justify-content: center justify-content: center
border-top: unset
background-color: transparent
.footer-headline .footer-headline
font-size: 16px font-size: 16px
.footer-social-links .footer-social-links
@@ -152,7 +187,7 @@ onMounted(async () => {
border-radius: 14px border-radius: 14px
background: var(--grey, #858585) background: var(--grey, #858585)
display: flex display: flex
padding: 0px 16px padding: 6px 20px
align-items: center align-items: center
flex: 0 1 0 flex: 0 1 0
color: black color: black
@@ -189,8 +224,14 @@ onMounted(async () => {
div div
font-size: 40px font-size: 40px
cursor: pointer cursor: pointer
-webkit-tap-highlight-color: transparent
&.active &.active
svg
path
color: var(--purple) color: var(--purple)
fill: var(--purple)
.modal-overlay .modal-overlay
background-color: rgb(15, 15, 15, 0.7) background-color: rgb(15, 15, 15, 0.7)
@@ -216,7 +257,7 @@ onMounted(async () => {
z-index: 100 z-index: 100
gap: 16px gap: 16px
@media (min-width: 992px) @media (min-width: 992px)
top: 142px top: 10%
right: 24px right: 24px
left: unset left: unset
transform: unset transform: unset
@@ -248,4 +289,10 @@ body:hover::-webkit-scrollbar-thumb
.toast-header, .toast-body .toast-header, .toast-body
font-size: 16px font-size: 16px
.Vue-Toastification__container
&.bloodline-toast-container
&.top-right
@media (min-width: 992px)
top: 100px
</style> </style>
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"contractName": "Bloodline", "contractName": "Bloodline",
"contractAddress": "0x51bF3df58D123e8EA43fb2189f18027FD36a08Af", "contractAddress": "0x16351Cd1f3F1eb010758ff9FCf7013f48B0f5495",
"abi": [ "abi": [
{ {
"inputs": [ "inputs": [
+97 -1
View File
@@ -1,6 +1,6 @@
{ {
"contractName": "LiquidityOwner", "contractName": "LiquidityOwner",
"contractAddress": "0xF8bc4Ce13263DD4e12070e3192be50310eF7C95a", "contractAddress": "0x460f41499B6dA662ce289b57ba62A75FBd753b5c",
"abi": [ "abi": [
{ {
"inputs": [ "inputs": [
@@ -132,6 +132,35 @@
"stateMutability": "pure", "stateMutability": "pure",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "int24",
"name": "tick",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"name": "_liquidityCanBeProvided",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -169,6 +198,54 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "int24",
"name": "tickCycle",
"type": "int24"
}
],
"name": "calculateTicksForRange1",
"outputs": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "int24",
"name": "tickCycle",
"type": "int24"
}
],
"name": "calculateTicksForRange2",
"outputs": [
{
"internalType": "int24",
"name": "tickLower",
"type": "int24"
},
{
"internalType": "int24",
"name": "tickUpper",
"type": "int24"
}
],
"stateMutability": "pure",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -211,6 +288,25 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "cycleTicks",
"outputs": [
{
"internalType": "int24",
"name": "",
"type": "int24"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "memeAltar", "name": "memeAltar",
+42 -102
View File
@@ -1,6 +1,6 @@
{ {
"contractName": "MemeAltar", "contractName": "MemeAltar",
"contractAddress": "0xE4F42F3f8B0E57b1054D457fe3b49a1A10B1aCEa", "contractAddress": "0xAa72C9dB8332c28b4ebcC36D927e967EFC98D78C",
"abi": [ "abi": [
{ {
"inputs": [ "inputs": [
@@ -53,6 +53,11 @@
"name": "CycleCompletedRegistrationFailed", "name": "CycleCompletedRegistrationFailed",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "GoalCannotBeZero",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "InsufficientOutputAmount", "name": "InsufficientOutputAmount",
@@ -215,42 +220,16 @@
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
{ {
"components": [ "indexed": true,
{ "internalType": "uint64",
"internalType": "uint40", "name": "b",
"name": "b1", "type": "uint64"
"type": "uint40"
}, },
{ {
"internalType": "uint40", "indexed": true,
"name": "m1", "internalType": "uint64",
"type": "uint40" "name": "m",
}, "type": "uint64"
{
"internalType": "uint40",
"name": "b2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b3",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m4",
"type": "uint40"
}
],
"indexed": false,
"internalType": "struct MemeAltar.BM",
"name": "_bm",
"type": "tuple"
} }
], ],
"name": "NewBM", "name": "NewBM",
@@ -309,41 +288,14 @@
{ {
"inputs": [ "inputs": [
{ {
"components": [ "internalType": "uint64",
{ "name": "newB",
"internalType": "uint40", "type": "uint64"
"name": "b1",
"type": "uint40"
}, },
{ {
"internalType": "uint40", "internalType": "uint64",
"name": "m1", "name": "newM",
"type": "uint40" "type": "uint64"
},
{
"internalType": "uint40",
"name": "b2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b3",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m4",
"type": "uint40"
}
],
"internalType": "struct MemeAltar.BM",
"name": "newBM",
"type": "tuple"
} }
], ],
"name": "adjustBM", "name": "adjustBM",
@@ -410,12 +362,12 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "bloodline", "name": "b",
"outputs": [ "outputs": [
{ {
"internalType": "contract Bloodline", "internalType": "uint64",
"name": "", "name": "",
"type": "address" "type": "uint64"
} }
], ],
"stateMutability": "view", "stateMutability": "view",
@@ -423,37 +375,12 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "bm", "name": "bloodline",
"outputs": [ "outputs": [
{ {
"internalType": "uint40", "internalType": "contract Bloodline",
"name": "b1", "name": "",
"type": "uint40" "type": "address"
},
{
"internalType": "uint40",
"name": "m1",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m2",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "b3",
"type": "uint40"
},
{
"internalType": "uint40",
"name": "m4",
"type": "uint40"
} }
], ],
"stateMutability": "view", "stateMutability": "view",
@@ -662,9 +589,9 @@
"name": "issuancePrice", "name": "issuancePrice",
"outputs": [ "outputs": [
{ {
"internalType": "uint256", "internalType": "uint128",
"name": "", "name": "",
"type": "uint256" "type": "uint128"
} }
], ],
"stateMutability": "view", "stateMutability": "view",
@@ -683,6 +610,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "m",
"outputs": [
{
"internalType": "uint64",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"contractName": "RewardLocker", "contractName": "RewardLocker",
"contractAddress": "0x2952253374973DE0ffbFe35269Ca13FaF28B935F", "contractAddress": "0x8b15b2CB5b019472C31aEf487BF700037c321F85",
"abi": [ "abi": [
{ {
"inputs": [ "inputs": [
File diff suppressed because one or more lines are too long
+5
View File
@@ -0,0 +1,5 @@
{
"contractName": "WETH",
"contractAddress": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
"contractAddressMainnet": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
}
+3
View File
@@ -0,0 +1,3 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.5332 0.223612C14.5688 -0.68935 16.3324 1.37298 15.6956 3.16362C13.5347 9.2395 14.8624 16.1404 19.3476 20.6276C23.8556 25.1377 30.7963 26.4633 36.8868 24.2619C38.659 23.6213 40.6637 25.369 39.7876 27.3579C39.7616 27.4167 39.7355 27.4752 39.7091 27.534C38.1498 30.9948 35.6553 34.2494 32.4281 36.4315C28.9883 38.7574 24.9319 40 20.7803 40H20.7783C15.9506 39.9948 11.2749 38.3095 7.5529 35.2332C3.83085 32.1569 1.2942 27.8809 0.377993 23.1382C-0.538209 18.3955 0.22314 13.4818 2.53147 9.23928C4.71976 5.21736 8.39949 2.09189 12.4733 0.250546L12.5332 0.223612Z" fill="#F9F9FA"/>
</svg>

After

Width:  |  Height:  |  Size: 731 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="30" height="40" viewBox="0 0 30 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.4808 0.762253C16.1401 0.28454 15.5867 0 14.9994 0C14.4107 0 13.8586 0.283234 13.5153 0.762253C9.85024 5.87744 0.667969 19.3317 0.667969 25.6686C0.667969 33.5835 7.08316 40 14.9981 40C22.9143 40 29.3308 33.5835 29.3308 25.6686C29.3321 19.3317 20.1459 5.87744 16.4808 0.762253Z" fill="#F9F9FA"/>
</svg>

After

Width:  |  Height:  |  Size: 410 B

+12
View File
@@ -0,0 +1,12 @@
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1478_31440)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.8333 12C11.8333 7.58797 15.498 7.6 19.9997 7.6C24.5035 7.6 28.1661 7.58797 28.1661 12C28.1661 16.412 24.5035 20 19.9997 20C15.498 20 11.8333 16.412 11.8333 12ZM39.9114 35.2719C38.4271 28.5539 33.7845 23.5959 27.674 21.3459C30.912 18.7919 32.8005 14.6619 32.1063 10.1399C31.302 4.89386 26.8472 0.695954 21.4697 0.0839537C14.0464 -0.762046 7.75014 4.89797 7.75014 12C7.75014 15.78 9.53858 19.1479 12.3274 21.3459C6.21487 23.5959 1.57433 28.5539 0.088048 35.2719C-0.450933 37.7139 1.558 40 4.10795 40H35.8915C38.4434 40 40.4524 37.7139 39.9114 35.2719Z" fill="#F9F9FA"/>
<path d="M17.2809 18.8008L16.4813 16.4008L15.2025 15.2008L19.3594 15.2008L18.0813 16.4008L17.2809 18.8008Z" fill="#F9F9FA"/>
<path d="M23.359 18.8008L22.5594 16.4008L21.2806 15.2008L25.4375 15.2008L24.1594 16.4008L23.359 18.8008Z" fill="#F9F9FA"/>
</g>
<defs>
<clipPath id="clip0_1478_31440">
<rect width="40" height="40" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long
+1
View File
@@ -20,5 +20,6 @@
&[disabled], &.btn--disabled &[disabled], &.btn--disabled
background-color: darken($purple, 10%) background-color: darken($purple, 10%)
cursor: not-allowed cursor: not-allowed
color: var(--white-dark)
&:hover,&:focus,&:active &:hover,&:focus,&:active
background-color: darken($purple, 10%), background-color: darken($purple, 10%),
-2
View File
@@ -34,8 +34,6 @@ body
display: flex display: flex
flex-direction: column flex-direction: column
height: 100vh height: 100vh
.footer
margin-top: auto
.container .container
margin-right: auto margin-right: auto
+11 -1
View File
@@ -9,6 +9,7 @@ $tertiary-dark: darken($tertiary, 20%)
$tertiary-light: lighten($tertiary, 20%) $tertiary-light: lighten($tertiary, 20%)
$white: #F9F9FA $white: #F9F9FA
$white-dark: darken($white, 20%)
$black: #0F0F0F $black: #0F0F0F
$grey: #858585 $grey: #858585
$grey-light: lighten($grey, 20%) $grey-light: lighten($grey, 20%)
@@ -31,7 +32,8 @@ $button-background-color: $black
--tertiary: #{$tertiary} --tertiary: #{$tertiary}
--tertiary-light: #{$tertiary-light} --tertiary-light: #{$tertiary-light}
--tertiary-dark: #{$tertiary-dark} --tertiary-dark: #{$tertiary-dark}
--white: #{#F9F9FA} --white: #{$white}
--white-dark: #{$white-dark}
--grey: #{$grey} --grey: #{$grey}
--grey-light: #{$grey-light} --grey-light: #{$grey-light}
--grey2: #{$grey2} --grey2: #{$grey2}
@@ -99,6 +101,14 @@ $button-background-color: $black
line-height: normal line-height: normal
// @media (min-width: 992px) // @media (min-width: 992px)
// font-size: 30px // font-size: 30px
.sub-header-2
font-family: Inter
font-style: normal
font-weight: 400
line-height: normal
font-size: 24px
@media (min-width: 992px)
font-size: 32px
// :root // :root
// --font-size-text: 16px // --font-size-text: 16px
+38 -17
View File
@@ -14,14 +14,15 @@
:slidesPerView="3" :slidesPerView="3"
:centeredSlides="false" :centeredSlides="false"
:initial-slide="0" :initial-slide="0"
:spaceBetween="IsMobile ? 35 : 0" :spaceBetween="0"
@swiper="onSwiper" @swiper="onSwiper"
> >
<swiper-slide class="blood-chart-element" v-for="coin in token" :key="coin.name"> <swiper-slide class="blood-chart-element" v-for="coin in token" :key="coin.name">
<div class="blood-chart-element-header"> <div class="blood-chart-element-header">
<div class="blood-chart-coin"> <div class="blood-chart-coin">
<template v-if="cycleStore.getCycleWinner.contractAddress === coin.contractAddress"> <template v-if="cycleStore.getCycleWinner.contractAddress === coin.contractAddress">
<img :src="coin.vampwinner2" alt="logo" /> <img class="logo" :src="coin.vamplogo" alt="logo" />
<img class="crown" src="/assets/img/winnerCrown.png" alt="" />
</template> </template>
<template v-else> <template v-else>
<img :src="coin.vamplogo" alt="logo" /> <img :src="coin.vamplogo" alt="logo" />
@@ -71,8 +72,13 @@
</div> </div>
</div> </div>
<div class="blood-chart-element-footer"> <div class="blood-chart-element-footer">
<div class="blood-chart-amount"> <div
{{ formatNumber(coin.amountInBLD) }} class="blood-chart-amount"
:title="formatBigIntDivision(coin.amountInBLD, 10n ** tokenStore.memeToken.decimals)"
>
{{
compactNumber(formatBigIntDivision(coin.amountInBLD, 10n ** tokenStore.memeToken.decimals))
}}
</div> </div>
<div>$BLOOD</div> <div>$BLOOD</div>
</div> </div>
@@ -95,10 +101,12 @@
<script setup> <script setup>
import { computed, ref, inject, onMounted } from "vue"; import { computed, ref, inject, onMounted } from "vue";
import { getPercentage, compactNumber, formatNumber } from "@/helper/helper.js"; import { getPercentage, formatNumber, compactNumber, formatBigIntDivision } from "@/helper/helper.js";
import { useCycleStore } from "@/stores/cycles"; import { useCycleStore } from "@/stores/cycles";
import { useMemeburnerStore } from "@/stores/memeburner"; import { useMemeburnerStore } from "@/stores/memeburner";
import { useTokenStore } from "@/stores/tokens";
import { Swiper, SwiperSlide } from "swiper/vue"; import { Swiper, SwiperSlide } from "swiper/vue";
// Import Swiper styles // Import Swiper styles
@@ -107,6 +115,9 @@ import "swiper/css/navigation";
import "swiper/css/pagination"; import "swiper/css/pagination";
const cycleStore = useCycleStore(); const cycleStore = useCycleStore();
const tokenStore = useTokenStore();
const isMobile = inject("isMobile");
const props = defineProps({ const props = defineProps({
data: Object, data: Object,
@@ -122,13 +133,15 @@ function onSwiper(swiper) {
swiperInstance.value = swiper; swiperInstance.value = swiper;
} }
const token = computed(() => props.data?.token); const token = computed(() => {
return props.data?.token.sort((a, b) => (a.amount > b.amount ? -1 : b.amount > a.amount ? 1 : 0));
});
//start with visual 5% of the filled bar, because otherwise the percentage number is not visible //start with visual 8% of the filled bar, because otherwise the percentage number is not visible
function getPercentageBloodChart(amount, goal) { function getPercentageBloodChart(amount, goal) {
let returnNumber = 5; let returnNumber = 8;
if ((Number(amount) / Number(goal)) * 100 < 5) { if ((Number(amount) / Number(goal)) * 100 < 8) {
returnNumber = 5; returnNumber = 8;
} else { } else {
returnNumber = (Number(amount) / Number(goal)) * 100; returnNumber = (Number(amount) / Number(goal)) * 100;
} }
@@ -143,11 +156,13 @@ function getPercentageBloodChart(amount, goal) {
justify-content: center justify-content: center
// margin-bottom: 80px // margin-bottom: 80px
position: relative position: relative
margin-top: 24px
.blood-chart .blood-chart
height: 750px height: 560px
width: 100% width: 100%
justify-content: space-around justify-content: space-around
display: inline-flex display: inline-flex
overflow: unset
@media (min-width: 992px) @media (min-width: 992px)
gap: 32px gap: 32px
width: unset width: unset
@@ -169,21 +184,31 @@ function getPercentageBloodChart(amount, goal) {
margin-right: auto margin-right: auto
position: relative position: relative
margin-bottom: 16px margin-bottom: 16px
overflow: hidden // overflow: hidden
height: 80px height: 80px
width: 80px width: 80px
@media (min-width: 992px) @media (min-width: 992px)
height: 72px height: 72px
width: 72px width: 72px
img img
&.logo
height: 100% height: 100%
width: 100% width: 100%
border: 1px solid yellow
border-radius: 50%
img
&.crown
position: absolute
top: -10px
transform: translate(-50%, -50%)
left: 50%
.blood-chart-coin-title .blood-chart-coin-title
text-align: center text-align: center
margin-bottom: 32px margin-bottom: 32px
.blood-chart-element-body .blood-chart-element-body
background-color: rgba(233, 233, 233, 0.2) background-color: rgba(233, 233, 233, 0.2)
flex: 0 0 500px flex: 1 1 100%
width: 60px width: 60px
border-radius: 8px 8px 40px 40px border-radius: 8px 8px 40px 40px
text-align: left text-align: left
@@ -213,10 +238,6 @@ function getPercentageBloodChart(amount, goal) {
.swiper-slide .swiper-slide
width: 80px width: 80px
.swiper-test
display: flex
flex-direction: column
.blood-arrow .blood-arrow
min-width: 30px min-width: 30px
File diff suppressed because one or more lines are too long
-1
View File
@@ -69,7 +69,6 @@ const props = defineProps({
display: flex display: flex
text-align: left text-align: left
gap: 16px gap: 16px
height: 56px
.token-logo .token-logo
margin-left: auto margin-left: auto
.connected-stake-buttons .connected-stake-buttons
+37 -17
View File
@@ -4,12 +4,12 @@
<template v-slot:body> <template v-slot:body>
<token-name-price <token-name-price
:name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name" :name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name"
:price="walletStore.memeToken?.unclaimedRewards" :price="formatNumber(walletStore.unclaimedRewards, 10n ** tokenStore.memeToken.decimals)"
></token-name-price> ></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline logo'"></token-logo> <token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline logo'"></token-logo>
</template> </template>
<template v-slot:actions> <template v-slot:actions>
<template v-if="walletStore.memeToken?.unclaimedRewards > 0"> <template v-if="walletStore.unclaimedRewards > 0n">
<Transition name="smooth"> <Transition name="smooth">
<div class="connected-stake-buttons" v-show="!stakeMenu"> <div class="connected-stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal mid-mid-text" @click="claimAll" v-if="stateStake === 0">Claim</div> <div class="btn btn-immortal mid-mid-text" @click="claimAll" v-if="stateStake === 0">Claim</div>
@@ -19,19 +19,32 @@
<div class="btn btn-immortal stake-button" disabled v-else-if="stateStake === 3"> <div class="btn btn-immortal stake-button" disabled v-else-if="stateStake === 3">
<loading-component></loading-component> <loading-component></loading-component>
</div> </div>
<div class="btn btn-immortal mid-mid-text" @click="openStake">Stake</div> <div class="btn btn-immortal mid-mid-text" @click="openStake" v-if="stateStake === 0">
Stake
</div>
</div> </div>
</Transition> </Transition>
<Transition name="smooth"> <Transition name="smooth">
<stake-menu <stake-menu
v-model="tokenNumber" v-model="tokenNumber"
@close="stakeMenu = false" @close="stakeMenu = false"
:amount="walletStore.memeToken?.unclaimedRewards" :amount="walletStore.unclaimedRewards"
:stake="stake" :stake="stake"
v-if="stakeMenu" v-if="stakeMenu"
> >
<template v-slot:body> <template v-slot:body>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 0"> <div
class="btn btn-immortal stake-button"
disabled
v-if="
tokenNumber > 0 &&
BigInt(tokenNumber) * 10n ** tokenStore.memeToken.decimals >
walletStore.unclaimedRewards
"
>
Insufficient Balance
</div>
<div class="btn btn-immortal stake-button" disabled v-else-if="stateClaimComp === 0">
Enter Amount Enter Amount
</div> </div>
<div <div
@@ -41,10 +54,10 @@
> >
Stake & Claim Rest Stake & Claim Rest
</div> </div>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 2"> <div class="btn btn-immortal stake-button" disabled v-else-if="stateClaimComp === 2">
Sign Transaction Sign Transaction
</div> </div>
<div class="btn btn-immortal stake-button" disabled v-if="stateClaimComp === 3"> <div class="btn btn-immortal stake-button" disabled v-else-if="stateClaimComp === 3">
<loading-component></loading-component> <loading-component></loading-component>
</div> </div>
<div <div
@@ -56,14 +69,19 @@
</template> </template>
<template v-slot:message-end> <template v-slot:message-end>
<div class="input-balance"> <div class="input-balance">
Balance: {{ formatNumber(walletStore.memeToken?.unclaimedRewards) }} Balance:
{{ formatNumber(walletStore.unclaimedRewards, 10n ** tokenStore.memeToken.decimals) }}
</div> </div>
</template> </template>
</stake-menu> </stake-menu>
</Transition> </Transition>
<div class="connected-stake-first-round small-text text-center"> </template>
You can claim, once the cycle is over. <template v-else-if="cycleStore.rewardsSacrificeCurrentCycle > 0n">
<div class="connected-stake-buttons">
<div class="btn btn-immortal mid-mid-text btn--disabled">Claim</div>
<div class="btn btn-immortal mid-mid-text btn--disabled">Stake</div>
</div> </div>
<div class="text-center">You can claim, once the cycle is over</div>
</template> </template>
<template v-else> <template v-else>
<div class="btn btn-immortal mid-mid-text text-center" @click="router.push({ name: 'home' })"> <div class="btn btn-immortal mid-mid-text text-center" @click="router.push({ name: 'home' })">
@@ -85,6 +103,7 @@ import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue"; import LoadingComponent from "@/components/LoadingComponent.vue";
import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue"; import StakeSuccessToast from "@/components/toasts/StakeSuccessToast.vue";
import { useCycleStore } from "@/stores/cycles";
import { useWalletStoreV2 } from "@/stores/walletV2"; import { useWalletStoreV2 } from "@/stores/walletV2";
import { useTokenStore } from "@/stores/tokens"; import { useTokenStore } from "@/stores/tokens";
import { useRewardLockerStore } from "@/stores/rewardlocker"; import { useRewardLockerStore } from "@/stores/rewardlocker";
@@ -97,6 +116,8 @@ const toast = useToast();
const rewardLockerStore = useRewardLockerStore(); const rewardLockerStore = useRewardLockerStore();
const walletStore = useWalletStoreV2(); const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const cycleStore = useCycleStore();
const router = useRouter(); const router = useRouter();
const props = defineProps({ const props = defineProps({
@@ -127,9 +148,8 @@ function openStake() {
async function stakeAndClaimAllCycles() { async function stakeAndClaimAllCycles() {
try { try {
const unclaimedRewards = walletStore.memeToken?.unclaimedRewards;
stateClaim.value = 2; stateClaim.value = 2;
const coefficient = (10000 * tokenNumber.value) / unclaimedRewards; const coefficient = BigInt(10000 * tokenNumber.value) / walletStore.unclaimedRewards;
var hash = await rewardLockerStore.stakeAndClaimAllCycles(coefficient); var hash = await rewardLockerStore.stakeAndClaimAllCycles(coefficient);
stateClaim.value = 3; stateClaim.value = 3;
const data = await waitForTransaction({ const data = await waitForTransaction({
@@ -144,9 +164,9 @@ async function stakeAndClaimAllCycles() {
// //
console.log("rewardData", rewardData); console.log("rewardData", rewardData);
//ClaimedReward (address staker, uint256 reward) //ClaimedReward (address staker, uint256 reward)
const outputClaim = Number(rewardData.topics[2]) / Math.pow(10, tokenStore.memeToken.decimals); const outputClaim = formatNumber(BigInt(rewardData.topics[2]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast( showSuccessToast(
formatNumber(outputClaim), outputClaim,
"Success!", "Success!",
"You just claimed and staked", "You just claimed and staked",
"Join the next cycle to increase your rewards and win with your clan" "Join the next cycle to increase your rewards and win with your clan"
@@ -175,9 +195,9 @@ async function claimAll() {
// //
console.log("rewardData", rewardData); console.log("rewardData", rewardData);
//ClaimedReward (address staker, uint256 reward) //ClaimedReward (address staker, uint256 reward)
const outputClaim = Number(rewardData.topics[2]) / Math.pow(10, tokenStore.memeToken.decimals); const outputClaim = formatNumber(BigInt(rewardData.topics[2]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast( showSuccessToast(
formatNumber(outputClaim), outputClaim,
"Success!", "Success!",
"You just claimed", "You just claimed",
"Join the next cycle to increase your rewards and win with your clan." "Join the next cycle to increase your rewards and win with your clan."
@@ -207,7 +227,7 @@ const stateClaimComp = computed(() => {
tokenNumber.value === null || tokenNumber.value === null ||
tokenNumber.value === "" || tokenNumber.value === "" ||
tokenNumber.value === 0 || tokenNumber.value === 0 ||
tokenNumber.value > walletStore.memeToken?.unclaimedRewards BigInt(tokenNumber.value) > walletStore.unclaimedRewards / 10n ** tokenStore.memeToken.decimals
) { ) {
returnState = 0; returnState = 0;
} else if (stateClaim.value === 2) { } else if (stateClaim.value === 2) {
+28 -18
View File
@@ -5,19 +5,25 @@
<div class="connectors-wrapper"> <div class="connectors-wrapper">
<div <div
class="connectors-element card" class="connectors-element card"
:class="[[connector.id]]"
v-for="connector in walletStore.config?.connectors" v-for="connector in walletStore.config?.connectors"
@click="connectWallet(connector)" @click="connectWallet(connector)"
> >
<div class="connector-icon"> <div class="connector-icon">
<template v-if="connector.id === 'injected'">
<template v-if="connector.name === 'MetaMask'">
<img :src="`/assets/img/connectors/metaMask.svg`" :alt="`${connector.name} Logo`" />
</template>
<template v-else>
<font-awesome-icon :icon="['fas', 'wallet']" />
</template>
</template>
<template v-else>
<img :src="`/assets/img/connectors/${connector.id}.svg`" :alt="`${connector.name} Logo`" /> <img :src="`/assets/img/connectors/${connector.id}.svg`" :alt="`${connector.name} Logo`" />
</template>
</div> </div>
<div class="connector-name"> <div class="connector-name">
<template
v-if="connector.id !== 'metaMask' || (connector.id === 'metaMask' && isMetaMaskInstalled())"
>
{{ connector.name }} {{ connector.name }}
</template>
<template v-else> Install {{ connector.name }} </template>
</div> </div>
</div> </div>
</div> </div>
@@ -30,7 +36,7 @@
<div class="connected-header-avatar"> <div class="connected-header-avatar">
<img :src="getblocky(walletStore.address)" alt="avatar" /> <img :src="getblocky(walletStore.address)" alt="avatar" />
</div> </div>
<div class="connected-header-address"> <div class="connected-header-address" :title="walletStore.address">
{{ getAddressShortName(walletStore.address) }} {{ getAddressShortName(walletStore.address) }}
</div> </div>
<div class="connected-header-logout" @click="disconnectWallet"> <div class="connected-header-logout" @click="disconnectWallet">
@@ -42,7 +48,9 @@
<div class="connected-token" v-for="token in walletStore.token"> <div class="connected-token" v-for="token in walletStore.token">
<token-name-price <token-name-price
:name="tokenStore.getToken(token.contractAddress).name" :name="tokenStore.getToken(token.contractAddress).name"
:price="token.balanceOf" :price="
formatNumber(token.balanceOf, 10n ** tokenStore.getToken(token.contractAddress).decimals)
"
></token-name-price> ></token-name-price>
<div class="connected-token-button"> <div class="connected-token-button">
<div class="bloodline-badge grey" @click="badgeClick(token)"> <div class="bloodline-badge grey" @click="badgeClick(token)">
@@ -71,7 +79,7 @@ import TokenNamePrice from "./TokenNamePrice.vue";
import TokenLogo from "./TokenLogo.vue"; import TokenLogo from "./TokenLogo.vue";
import StakeComponentV1 from "@/components/StakeComponentV1.vue"; import StakeComponentV1 from "@/components/StakeComponentV1.vue";
import { getAddressShortName, getblocky } from "@/helper/helper.js"; import { getAddressShortName, getblocky, formatNumber } from "@/helper/helper.js";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import { disconnect } from "@wagmi/core"; import { disconnect } from "@wagmi/core";
@@ -95,10 +103,9 @@ async function disconnectWallet() {
} }
} }
function isMetaMaskInstalled() { function isMetaMaskInstalled(connector) {
//metamask is not installed but showing true, is that a bug? const metamaskInstalled = connector?.options?.getProvider();
if (typeof window.ethereum !== "undefined" && window.ethereum?.isMetaMask && !window.ethereum.isBraveWallet) { if (metamaskInstalled) {
console.log("MetaMask is installed!", window.ethereum);
return true; return true;
} }
return false; return false;
@@ -109,7 +116,6 @@ function isMetaMaskInstalled() {
//we could also show buy, if there is no pepe //we could also show buy, if there is no pepe
function badgeClick(token) { function badgeClick(token) {
var tokenData = tokenStore.getToken(token.contractAddress); var tokenData = tokenStore.getToken(token.contractAddress);
tokenStore.activeToken = tokenData;
if (tokenStore.memeToken.contractAddress === token.contractAddress) { if (tokenStore.memeToken.contractAddress === token.contractAddress) {
//buy //buy
window.open( window.open(
@@ -124,10 +130,7 @@ function badgeClick(token) {
//special case for metaMask, but I think that is the most used wallet //special case for metaMask, but I think that is the most used wallet
async function connectWallet(connector) { async function connectWallet(connector) {
if (connector.id === "metaMask" && !isMetaMaskInstalled()) { console.log("connector", connector);
window.open(" https://metamask.io/", "_blank");
return;
}
instance.parent.emit("update:modelValue", false); instance.parent.emit("update:modelValue", false);
await walletStore.connectWallet(toRaw(connector)); await walletStore.connectWallet(toRaw(connector));
} }
@@ -151,6 +154,14 @@ async function connectWallet(connector) {
&:hover, &:active, &:focus &:hover, &:active, &:focus
background-color: lighten(#858585, 20%) background-color: lighten(#858585, 20%)
cursor: pointer cursor: pointer
&.injected
.connector-icon
background-color: white
display: flex
justify-content: center
align-items: center
svg
font-size: 25px
.connector-icon .connector-icon
border-radius: 12px border-radius: 12px
width: 40px width: 40px
@@ -194,7 +205,6 @@ async function connectWallet(connector) {
display: flex display: flex
gap: 16px gap: 16px
align-items: center align-items: center
height: 56px
.connected-token-button .connected-token-button
margin-left: auto margin-left: auto
.bloodline-badge .bloodline-badge
-15
View File
@@ -147,21 +147,6 @@ onBeforeUnmount(() => {
color: white color: white
.navbar-center .navbar-center
display: flex display: flex
margin-left: auto
.navbar-social-links
display: flex
gap: 18px
.social-bloodline-badge
font-size: 16px
padding: 8px 16px 8px 16px
border-radius: 14px
background-color: #0F0F0F
display: flex
&:hover,&:active,&:focus
background-color: lighten(#0F0F0F, 10%)
cursor: pointer
.social-bloodline-badge-icon
margin-right: 8px
.navbar-end .navbar-end
display: flex display: flex
margin-left: auto margin-left: auto
+4 -3
View File
@@ -1,7 +1,8 @@
<template> <template>
<div class="rewards-wrapper"> <div class="rewards-wrapper">
<div class="rewards-headline low-mid-text"> <div class="rewards-headline low-mid-text">
{{ props.title }} <div class="rewards-title">{{ props.title }}</div>
<div class="rewards-sub-title" v-if="props.subTitle">{{ props.subTitle }}</div>
</div> </div>
<div class="rewards-inner"> <div class="rewards-inner">
<token-name-price name="$BLOOD" :price="props.amount"></token-name-price> <token-name-price name="$BLOOD" :price="props.amount"></token-name-price>
@@ -16,8 +17,9 @@ import TokenLogo from "@/components/TokenLogo.vue";
const props = defineProps({ const props = defineProps({
title: String, title: String,
subTitle: String,
info: String, info: String,
amount: String, amount: [String, Number],
image: String, image: String,
}); });
</script> </script>
@@ -33,6 +35,5 @@ const props = defineProps({
padding: 0 6px 6px 6px padding: 0 6px 6px 6px
border-bottom: 1px solid var(--grey, #858585) border-bottom: 1px solid var(--grey, #858585)
justify-content: space-between justify-content: space-between
height: 56px
box-sizing: content-box box-sizing: content-box
</style> </style>
+70 -34
View File
@@ -1,5 +1,5 @@
<template> <template>
<div class="sacrifice-wrapper card card--glow bloodline-wrapper"> <div class="sacrifice-wrapper card card--glow">
<div class="sacrifice-headline">Select Sacrifice</div> <div class="sacrifice-headline">Select Sacrifice</div>
<div class="sacrifice-select-tokens"> <div class="sacrifice-select-tokens">
<div class="sacrifice-tokens"> <div class="sacrifice-tokens">
@@ -25,34 +25,41 @@
</div> </div>
</div> </div>
<div class="sacrifice-from-to-wrapper" v-if="activeToken.contractAddress"> <div class="sacrifice-from-to-wrapper" v-if="activeToken.contractAddress">
<div <div class="sacrifice-from-wrapper bloodline-border bloodline-border--variant1 purple">
:class="{
'sacrifice-from-wrapper': true,
'bloodline-border': true,
'bloodline-border--variant1': true,
purple: true,
}"
>
<token-input <token-input
:modelValue="sacrificeStore.sacrificeNumber" :modelValue="sacrificeStore.sacrificeNumber / 10n ** activeToken.decimals"
@input=" @input="
($event) => { ($event) => {
sacrificeStore.sacrificeNumber = $event.target.value; const value = BigInt($event.target.value) * 10n ** activeToken.decimals;
processChange($event.target.value); sacrificeStore.sacrificeNumber = value;
processChange(value);
} }
" "
:max="activeWalletToken?.balanceOf" :max="activeWalletToken?.balanceOf"
:logo="activeToken.logo" :logo="activeToken.logo"
> >
<template v-slot:message> <template v-slot:message>
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(10000000)">+10m</div> <div
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(100000000)">+100m</div> class="sacrifice-adder-step bloodline-badge"
<div class="sacrifice-adder-step bloodline-badge" @click="addTokens(1000000000)">+1b</div> v-for="steps in activeToken.addSteps"
:key="steps.name"
@click="addTokens(steps.amount)"
>
<template
v-if="
!walletStore.connected ||
sacrificeStore.sacrificeNumber < activeWalletToken?.balanceOf
"
>
+{{ steps.name }}
</template> </template>
<template v-slot:message-end v-if="activeWalletToken?.balanceOf"> <template v-else> -{{ steps.name }} </template>
</div>
</template>
<template v-slot:message-end v-if="activeWalletToken?.balanceOf >= 0">
<div class="input-balance tiny-text"> <div class="input-balance tiny-text">
Balance: Balance:
{{ activeWalletToken?.balanceOf }} {{ formatNumber(activeWalletToken?.balanceOf, 10n ** activeToken.decimals) }}
</div> </div>
<div class="input-max tiny-text" @click="addMaxTokens">Max</div> <div class="input-max tiny-text" @click="addMaxTokens">Max</div>
</template> </template>
@@ -70,7 +77,10 @@
}" }"
> >
<div class="sacrifice-to-body"> <div class="sacrifice-to-body">
<token-name-price name="$BLOOD" :price="`≈${formatNumber(output)}`"></token-name-price> <token-name-price
name="$BLOOD"
:price="`≈${formatNumber(output, 10n ** activeToken.decimals)}`"
></token-name-price>
<token-logo :img="activeToken.vamp.logo" :size="64" :alt="activeToken.vamp.name"></token-logo> <token-logo :img="activeToken.vamp.logo" :size="64" :alt="activeToken.vamp.name"></token-logo>
</div> </div>
@@ -90,7 +100,9 @@
> >
No Staking Bonus No Staking Bonus
</div> </div>
<div class="mid-mid-text" v-else>+ {{ stakingOutput }} Staking Bonus</div> <div class="mid-mid-text" v-else>
+ {{ formatNumber(stakingOutput, 10n ** activeToken.decimals) }} Staking Bonus
</div>
<div class="icon"> <div class="icon">
<font-awesome-icon icon="chevron-down" /> <font-awesome-icon icon="chevron-down" />
</div> </div>
@@ -178,6 +190,7 @@ import { debounce, formatNumber } from "@/helper/helper.js";
const isMobile = inject("isMobile"); const isMobile = inject("isMobile");
const showPanel = inject("showPanel"); const showPanel = inject("showPanel");
const splashBlood = inject("splashBlood");
const walletStore = useWalletStoreV2(); const walletStore = useWalletStoreV2();
@@ -192,6 +205,8 @@ const output = ref(0);
const stakingOutput = ref(null); const stakingOutput = ref(null);
const blockEvent = ref(null); const blockEvent = ref(null);
const approveToast = ref(null); const approveToast = ref(null);
const addOperator = ref(true);
const splashesUsed = ref([]);
/** /**
* state 0 enter amount * state 0 enter amount
* state 1 rdy to go * state 1 rdy to go
@@ -215,7 +230,7 @@ const stateComputed = computed(() => {
if ( if (
sacrificeStore.sacrificeNumber === null || sacrificeStore.sacrificeNumber === null ||
sacrificeStore.sacrificeNumber === "" || sacrificeStore.sacrificeNumber === "" ||
sacrificeStore.sacrificeNumber === 0 sacrificeStore.sacrificeNumber === 0n
) { ) {
returnState = 0; returnState = 0;
} else if (sacrificeStore.sacrificeState === 2) { } else if (sacrificeStore.sacrificeState === 2) {
@@ -233,6 +248,7 @@ const stateComputed = computed(() => {
}); });
const processChange = debounce(async (value) => { const processChange = debounce(async (value) => {
const rewardValue = await sacrificeStore.getRewardsFor(value, activeToken.value); const rewardValue = await sacrificeStore.getRewardsFor(value, activeToken.value);
console.log("rewardValue", rewardValue);
output.value = rewardValue.output; output.value = rewardValue.output;
stakingOutput.value = rewardValue.staking; stakingOutput.value = rewardValue.staking;
}); });
@@ -258,6 +274,7 @@ onBeforeUnmount(() => {
async function approveToken(amount) { async function approveToken(amount) {
try { try {
console.log("amount", amount);
sacrificeStore.sacrificeState = 2; sacrificeStore.sacrificeState = 2;
const hash = await tokenStore.approveToken(amount); const hash = await tokenStore.approveToken(amount);
sacrificeStore.sacrificeState = 3; sacrificeStore.sacrificeState = 3;
@@ -267,7 +284,7 @@ async function approveToken(amount) {
console.log("data", data); console.log("data", data);
activeToken.value.allowance = await tokenStore.allowance(); activeToken.value.allowance = await tokenStore.allowance();
sacrificeStore.sacrificeState = 1; sacrificeStore.sacrificeState = 1;
approveToast.value = showApprovedToast(); showApprovedToast();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
throw new Error(error); throw new Error(error);
@@ -277,15 +294,25 @@ async function approveToken(amount) {
} }
async function addTokens(value) { async function addTokens(value) {
sacrificeStore.sacrificeNumber = Number(sacrificeStore.sacrificeNumber) + Number(value); if (!walletStore.connected || sacrificeStore.sacrificeNumber < activeWalletToken.value?.balanceOf) {
sacrificeStore.sacrificeNumber = BigInt(sacrificeStore.sacrificeNumber) + value;
} else {
sacrificeStore.sacrificeNumber = sacrificeStore.sacrificeNumber - value;
if (sacrificeStore.sacrificeNumber < 0n) {
sacrificeStore.sacrificeNumber = 0n;
}
}
const rewardValue = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, activeToken.value); const rewardValue = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, activeToken.value);
output.value = rewardValue.output; output.value = rewardValue.output;
stakingOutput.value = rewardValue.staking; stakingOutput.value = rewardValue.staking;
} }
async function addMaxTokens() { async function addMaxTokens() {
sacrificeStore.sacrificeNumber = activeWalletToken.value.balanceOf; addOperator.value = !addOperator.value;
sacrificeStore.sacrificeNumber = activeWalletToken.value?.balanceOf;
const rewardValue = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, activeToken.value); const rewardValue = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, activeToken.value);
console.log("rewardValue", rewardValue);
output.value = rewardValue.output; output.value = rewardValue.output;
stakingOutput.value = rewardValue.staking; stakingOutput.value = rewardValue.staking;
} }
@@ -301,26 +328,34 @@ function showApprovedToast(value, header, subheader, info) {
subheader: subheader, subheader: subheader,
info: info, info: info,
}, },
// Listen and react to events using callbacks. In this case we listen for listeners: {
// the "click" event emitted when clicking the toast button // sacrificed: showSplash,
listeners: {}, },
}; };
// Render the toast and its contents // Render the toast and its contents
return toast(content, { return toast(content, {
position: "top-right", position: "top-right",
icon: false, icon: false,
timeout: 5000,
closeOnClick: false, closeOnClick: false,
// toastClassName: "modal-overlay", // toastClassName: "modal-overlay",
hideProgressBar: true, hideProgressBar: true,
timeout: false,
toastClassName: "approve-toast toast-card", toastClassName: "approve-toast toast-card",
}); });
} }
function showSplash() {
splashBlood.value++;
}
//call function in the store and remove icon, //call function in the store and remove icon,
async function sacrificeToken() { async function sacrificeToken() {
await sacrificeStore.sacrificeToken(sacrificeStore.sacrificeNumber, activeToken.value); console.log("activeToken.value", activeToken.value);
var result = await sacrificeStore.sacrificeToken(sacrificeStore.sacrificeNumber, activeToken.value);
if (result) {
showSplash();
}
toast.dismiss(approveToast.value); toast.dismiss(approveToast.value);
} }
@@ -328,8 +363,8 @@ async function changeActiveToken(token) {
console.log("changeActiveToken"); console.log("changeActiveToken");
tokenStore.activeToken = token; tokenStore.activeToken = token;
if (walletStore.connected) { if (walletStore.connected) {
//TODO, wenn connected, dann all diese Daten laden? // //TODO, wenn connected, dann all diese Daten laden?
tokenStore.activeToken.balance = await walletStore.getTokenBalance(token); // tokenStore.activeToken.balance = await walletStore.getTokenBalance(token);
tokenStore.activeToken.allowance = Number(await tokenStore.allowance()); tokenStore.activeToken.allowance = Number(await tokenStore.allowance());
} }
var rewards = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, token); var rewards = await sacrificeStore.getRewardsFor(sacrificeStore.sacrificeNumber, token);
@@ -453,8 +488,10 @@ async function changeActiveToken(token) {
.value-adder .value-adder
display: flex display: flex
gap: 6px gap: 6px
flex-wrap: wrap
.sacrifice-adder-step .sacrifice-adder-step
font-size: 14px font-size: 12px
align-items: center
background: var(--grey, #858585) background: var(--grey, #858585)
color: var(--midnight-black, #0F0F0F) color: var(--midnight-black, #0F0F0F)
&:hover, &:hover,
@@ -462,8 +499,8 @@ async function changeActiveToken(token) {
&:focus &:focus
background-color: var(--grey-light) background-color: var(--grey-light)
cursor: pointer cursor: pointer
@media (min-width: 992px) // @media (min-width: 992px)
font-size: 12px // font-size: 12px
// .sacrifice-adder-balance // .sacrifice-adder-balance
// margin-left: auto // margin-left: auto
// .sacrifice-adder-max // .sacrifice-adder-max
@@ -482,7 +519,6 @@ async function changeActiveToken(token) {
.sacrifice-to-body .sacrifice-to-body
display: flex display: flex
justify-content: space-between justify-content: space-between
height: 56px
.sacrificed-info .sacrificed-info
display: flex display: flex
padding: 8px 24px padding: 8px 24px
+93 -39
View File
@@ -31,55 +31,61 @@
<div class="connected-stake-body"> <div class="connected-stake-body">
<slot name="body"> <slot name="body">
<token-name-price <token-name-price
:name="tokenStore.getToken(walletStore.memeToken?.contractAddress)?.name" name="$BLOOD staked"
:price="formatNumber(walletStore.memeToken?.staked)" :price="formatNumber(walletStore.staked, 10n ** tokenStore.memeToken.decimals)"
></token-name-price> ></token-name-price>
<token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline-token'"></token-logo> <token-logo img="/assets/img/token/bloodline.png" :alt="'bloodline-token'"></token-logo>
<token-name-price class="stake-reward" name="Extra Reward" price="+25%"></token-name-price> <token-name-price :variant="true" class="stake-reward" name="Bonus" price="+25%"></token-name-price>
</slot> </slot>
</div> </div>
<slot name="actions"> <slot name="actions">
<div class="connected-stake-buttons" v-if="!stakeMenu"> <div class="connected-stake-buttons" v-if="!stakeMenu">
<div class="mid-mid-text text-center" disabled v-if="!walletStore.connected"> <template v-if="!walletStore.connected">
Please Connect Your Wallet <div class="mid-mid-text text-center" disabled>Please Connect Your Wallet</div>
</div> </template>
<div <template v-else-if="walletStore.connected && !ableToUnstake">
class="btn btn-immortal mid-mid-text" <div class="btn btn-immortal mid-mid-text" disabled v-if="cycleStore.currentCycle === 1">
disabled
v-if="walletStore.connected && cycleStore.currentCycle === 1"
>
Stake Stake
</div> </div>
<div <div
class="btn btn-immortal mid-mid-text" class="btn btn-immortal mid-mid-text"
v-else-if="walletStore.connected && cycleStore.currentCycle > 1" v-else-if="cycleStore.currentCycle > 1"
@click="openStake" @click="openStake"
> >
Stake Stake
</div> </div>
<div <div
v-if=" v-if="(walletStore.memeToken?.staked === 0n && !stakeonly) || cycleStore.currentCycle === 1"
walletStore.connected &&
((walletStore.memeToken?.staked === 0 && !stakeonly) || cycleStore.currentCycle === 1)
"
class="btn btn-immortal btn--disabled mid-mid-text" class="btn btn-immortal btn--disabled mid-mid-text"
> >
Unstake Unstake
</div> </div>
<div <div v-else-if="!stakeonly" class="btn btn-immortal mid-mid-text" @click="openUnstake">
v-else-if="walletStore.connected && !stakeonly" Order Unstake
class="btn btn-immortal mid-mid-text"
@click="openUnstake"
>
Unstake
</div> </div>
</template>
<template v-else-if="walletStore.connected && ableToUnstake">
<div
class="btn btn-immortal mid-mid-text text-center"
v-if="unstakeState === 0 && walletStore.orderedUnstakedAmount > 0n && ableToUnstake"
@click="unstake"
>
Claim Unstaked $BLOOD
</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="unstakeState === 1">
Sign Transaction
</div>
<div class="btn btn--disabled mid-mid-text text-center" v-else-if="unstakeState === 2">
<loading-component></loading-component>
</div>
</template>
</div> </div>
<Transition name="smooth"> <Transition name="smooth">
<stake-menu <stake-menu
v-model="tokenNumber" v-model="tokenNumber"
@close="stakeMenu = false" @close="stakeMenu = false"
:stake="stake" :stake="stake"
:amount="walletStore.memeToken?.balanceOf" :amount="walletStore.balanceOf"
v-if="stakeMenu & !unstakeMenu" v-if="stakeMenu & !unstakeMenu"
> >
<template v-slot:body> <template v-slot:body>
@@ -103,7 +109,10 @@
</div> </div>
</template> </template>
<template v-slot:message-end> <template v-slot:message-end>
<div class="input-balance">Balance: {{ walletStore.memeToken?.balanceOf }}</div> <div class="input-balance">
Balance:
{{ formatNumber(walletStore.balanceOf, 10n ** tokenStore.memeToken.decimals) }}
</div>
</template> </template>
</stake-menu> </stake-menu>
<div class="unstake-menu" v-else-if="stakeMenu & unstakeMenu"> <div class="unstake-menu" v-else-if="stakeMenu & unstakeMenu">
@@ -130,9 +139,17 @@
</div> </div>
</div> </div>
</Transition> </Transition>
<div class="connected-stake-first-round small-text text-center" v-if="cycleStore.currentCycle === 0"> <div class="connected-stake-first-round small-text text-center" v-if="cycleStore.currentCycle === 1">
No $BLOOD on the market. Staking is activated after the first cycle is finished. No $BLOOD on the market. Staking is activated after the first cycle is finished.
</div> </div>
<div
class="connected-stake-first-round small-text text-center"
v-if="walletStore.orderedUnstakedAmount > 0n && !ableToUnstake"
>
You can claim
{{ formatNumber(walletStore.orderedUnstakedAmount, 10n ** tokenStore.memeToken.decimals) }}
$BLOOD next cycle.
</div>
</slot> </slot>
<slot></slot> <slot></slot>
</div> </div>
@@ -172,6 +189,11 @@ const props = defineProps({
required: false, required: false,
default: null, default: null,
}, },
dense: {
type: Boolean,
required: false,
default: false,
},
}); });
const stakeMenu = ref(false); const stakeMenu = ref(false);
@@ -188,6 +210,7 @@ const loading = ref(false);
* state 4 staked * state 4 staked
*/ */
const state = ref(0); const state = ref(0);
const unstakeState = ref(0);
function openStake() { function openStake() {
stake.value = true; stake.value = true;
@@ -201,6 +224,31 @@ function openUnstake() {
stakeMenu.value = true; stakeMenu.value = true;
} }
async function unstake() {
try {
unstakeState.value = 1;
const hash = await rewardLockerStore.unstake();
unstakeState.value = 2;
const data = await waitForTransaction({
hash: hash,
});
var rewardData = data.logs.find((logObject) => {
return logObject.topics.find(
(topic) => topic === "0xb89343427f692590c388d6346a8e42ea497eb6682a04db1a53f77ea81771ca91"
);
});
console.log("rewardData", rewardData);
const outputClaim = formatNumber(BigInt(rewardData.topics[3]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast(outputClaim, "Success!", "You just unstaked");
await walletStore.loadWalletData();
} catch (error) {
console.error("unstake", error);
} finally {
unstakeState.value = 0;
}
}
async function orderUnstake() { async function orderUnstake() {
try { try {
state.value = 2; state.value = 2;
@@ -212,28 +260,25 @@ async function orderUnstake() {
state.value = 4; state.value = 4;
var rewardData = data.logs.find((logObject) => { var rewardData = data.logs.find((logObject) => {
return logObject.topics.find( return logObject.topics.find(
(topic) => topic === "0xd0813ff03c470dcc7baa9ce36914dc2febdfd276d639deffaac383fd3db42ba3" (topic) => topic === "0xf86340d97020c624010a208b733db95795281fbc45cb6e6a40d161f91fa3e4a0"
); );
}); });
console.log("rewardData", rewardData); console.log("rewardData", rewardData);
const outputClaim = Number(rewardData.topics[2]) / Math.pow(10, tokenStore.memeToken.decimals); const outputClaim = formatNumber(BigInt(rewardData.topics[3]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast( showSuccessToast(outputClaim, "Success!", "You just unstaked", "You can claim your stake next cycle.");
formatNumber(outputClaim), stakeMenu.value = false;
"Success!",
"You just unstaked",
"You can claim your stake next cycle."
);
await walletStore.loadWalletData();
} catch (error) { } catch (error) {
console.error("orderUnstake", error); console.error("orderUnstake", error);
} finally { } finally {
await walletStore.loadWalletData();
state.value = 0; state.value = 0;
} }
} }
async function stakeToken() { async function stakeToken() {
try { try {
console.log("stakeToken");
state.value = 2; state.value = 2;
const hash = await rewardLockerStore.stakeBloodline(tokenNumber.value); const hash = await rewardLockerStore.stakeBloodline(tokenNumber.value);
state.value = 3; state.value = 3;
@@ -248,17 +293,17 @@ async function stakeToken() {
// //
console.log("rewardData", rewardData); console.log("rewardData", rewardData);
const outputClaim = Number(rewardData.topics[3]) / Math.pow(10, tokenStore.memeToken.decimals); const outputClaim = formatNumber(BigInt(rewardData.topics[3]), 10n ** tokenStore.memeToken.decimals);
console.log("data", data); console.log("data", data);
state.value = 4; state.value = 0;
await walletStore.loadWalletData();
showSuccessToast( showSuccessToast(
formatNumber(outputClaim), outputClaim,
"Success!", "Success!",
"You just staked", "You just staked",
"Your next sacrifice will get an extra staking bonus as a reward." "Your next sacrifice will get an extra staking bonus as a reward."
); );
//reload data await walletStore.loadWalletData();
stakeMenu.value = false;
} catch (error) { } catch (error) {
console.error(error); console.error(error);
throw new Error(error); throw new Error(error);
@@ -267,6 +312,15 @@ async function stakeToken() {
} }
} }
const ableToUnstake = computed(() => {
var cycleList = walletStore.memeToken?.orderedUnstakedCycles?.findIndex((obj) => obj.result > 0n);
console.log("cycleList", cycleList);
if (cycleList && cycleList > -1 && cycleList + 1 <= cycleStore.currentCycle) {
return true;
}
return false;
});
const stateStake = computed(() => { const stateStake = computed(() => {
let returnState = 0; let returnState = 0;
if (state.value === 2) { if (state.value === 2) {
+25 -13
View File
@@ -2,10 +2,10 @@
<div class="stake-menu"> <div class="stake-menu">
<token-input :modelValue="props.modelValue" @input="emit('update:modelValue', Number($event.target.value))"> <token-input :modelValue="props.modelValue" @input="emit('update:modelValue', Number($event.target.value))">
<template v-slot:message> <template v-slot:message>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(25)">25%</div> <div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(25n)">25%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(50)">50%</div> <div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(50n)">50%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(75)">75%</div> <div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(75n)">75%</div>
<div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(100)">100%</div> <div class="stake-adder-step bloodline-badge grey" @click="addTokensPercent(100n)">100%</div>
</template> </template>
<template v-slot:message-end> <template v-slot:message-end>
<slot name="message-end"> </slot> <slot name="message-end"> </slot>
@@ -14,7 +14,13 @@
<div class="stake-menu-actions"> <div class="stake-menu-actions">
<slot name="body"> <slot name="body">
<div class="input-balance">Balance: {{ walletStore.memeToken.balanceOf }}</div> <div class="input-balance">Balance: {{ walletStore.memeToken.balanceOf }}</div>
<div class="btn btn-immortal stake-button" @click="stakeBloodline" v-if="props.stake">Stake</div> <div
class="btn btn-immortal stake-button"
@click="rewardLockerStore.stakeBloodline(tokenNumber)"
v-if="props.stake"
>
Stake
</div>
<div class="btn btn-immortal stake-button" @click="unstakeBloodline" v-else>Unstake for Next Cycle</div> <div class="btn btn-immortal stake-button" @click="unstakeBloodline" v-else>Unstake for Next Cycle</div>
<div class="btn btn-immortal black" @click="emit('close')">Cancel</div> <div class="btn btn-immortal black" @click="emit('close')">Cancel</div>
</slot> </slot>
@@ -30,6 +36,7 @@ import { useWalletStoreV2 } from "@/stores/walletV2";
import { useRewardLockerStore } from "@/stores/rewardlocker"; import { useRewardLockerStore } from "@/stores/rewardlocker";
import { useTokenStore } from "@/stores/tokens"; import { useTokenStore } from "@/stores/tokens";
import { createPermitObject, getSignatureRSV } from "@/helper/blockchain.js"; import { createPermitObject, getSignatureRSV } from "@/helper/blockchain.js";
import { formatNumber } from "@/helper/helper.js";
import { signTypedData } from "@wagmi/core"; import { signTypedData } from "@wagmi/core";
@@ -39,24 +46,28 @@ const tokenStore = useTokenStore();
const props = defineProps({ const props = defineProps({
stake: Boolean, stake: Boolean,
modelValue: Number, modelValue: [Number, BigInt],
amount: Number, amount: [Number, BigInt],
}); });
const emit = defineEmits(["close", "update:modelValue"]); const emit = defineEmits(["close", "update:modelValue"]);
async function addTokensPercent(value) { async function addTokensPercent(value) {
console.log("value", value); console.log("value", value);
console.log(walletStore.memeToken.balanceOf); console.log("props.amount", props.amount);
let amount; let amount;
if (props.amount !== undefined || props.amount !== null) { if (props.amount !== undefined || props.amount !== null) {
amount = (props.amount * value) / 100; //todo function to calculate correct bigInt value (maybe use string and split)
amount = (BigInt(props.amount) * value) / 100n;
} else if (props.stake) { } else if (props.stake) {
amount = (walletStore.memeToken.balanceOf * value) / 100; amount = (walletStore.memeToken.balanceOf * value) / 100n;
} else { } else {
amount = (walletStore.memeToken.staked * value) / 100; amount = (walletStore.memeToken.staked * value) / 100n;
} }
emit("update:modelValue", Number(amount)); console.log("amount123", amount);
amount = amount / 10n ** tokenStore.memeToken.decimals;
console.log("amount", amount);
emit("update:modelValue", amount);
} }
async function unstakeBloodline() { async function unstakeBloodline() {
@@ -78,11 +89,12 @@ async function unstakeBloodline() {
async function stakeBloodline() { async function stakeBloodline() {
try { try {
console.log("stakeBloodline");
const fromAddress = walletStore.address; const fromAddress = walletStore.address;
const spender = rewardLockerStore.config.contractAddress; const spender = rewardLockerStore.config.contractAddress;
const deadline = Date.now() + 20 * 60; const deadline = Date.now() + 20 * 60;
const decimals = tokenStore.getToken(walletStore.memeToken.contractAddress).decimals; const decimals = tokenStore.getToken(walletStore.memeToken.contractAddress).decimals;
const value = (tokenNumber.value * Math.pow(10, decimals)).toString(); const value = BigInt(tokenNumber.value) * 10n ** decimals;
const nonce = await tokenStore.memeToken.contract.read.nonces([fromAddress]); const nonce = await tokenStore.memeToken.contract.read.nonces([fromAddress]);
const { types, message, domain, primaryType } = createPermitObject( const { types, message, domain, primaryType } = createPermitObject(
fromAddress, fromAddress,
+94 -39
View File
@@ -23,31 +23,38 @@
<rewards-wrapper <rewards-wrapper
title="Sacrafice Reward" title="Sacrafice Reward"
coin="$BLOOD" coin="$BLOOD"
:amount="formatNumber(getCurrentCycleData?.rewards_sacrifice)" :amount="formatNumber(rewardsSacrifice, 10n ** tokenStore.memeToken.decimals)"
image="/assets/img/vampir.png" image="/assets/img/vampir.png"
/> />
<rewards-wrapper <rewards-wrapper
title="Staking Bonus" title="Staking Bonus"
coin="$BLOOD" coin="$BLOOD"
:amount="formatNumber(getCurrentCycleData?.rewards_staking)" :amount="formatNumber(rewardsStaking, 10n ** tokenStore.memeToken.decimals)"
info="max: 312m"
image="/assets/img/vampir.png" image="/assets/img/vampir.png"
/> />
<rewards-wrapper <rewards-wrapper
title="Clan Bonus" title="Clan Bonus"
:subTitle="rewardsClan > 0 ? clanBonusPercentage : null"
coin="$BLOOD" coin="$BLOOD"
:amount="formatNumber(getCurrentCycleData?.rewards_clan)" :amount="formatNumber(rewardsClan, 10n ** tokenStore.memeToken.decimals)"
image="/assets/img/vampir.png" :image="
activeCycle === currentCycle || !cycleStore.getCurrentCycleData?.winner.vamplogo
? '/assets/img/token/notoken.png'
: cycleStore.getCurrentCycleData?.winner.vamplogo
"
/> />
</div> </div>
<div class="rewards-total-wrapper"> <div class="rewards-total-wrapper">
<div class="rewards-total-headline sub-header">Total Reward</div> <div class="rewards-total-headline sub-header">Total Reward</div>
<div class="rewards-total-inner bloodline-border bloodline-border--variant1"> <div
class="rewards-total-inner bloodline-border bloodline-border--variant1"
:class="{ purple: rewardsTotal > 0n && activeCycle !== currentCycle }"
>
<token-name-price <token-name-price
name="$BLOOD" name="$BLOOD"
:price="formatNumber(getCurrentCycleData?.rewards_total)" :price="formatNumber(rewardsTotal, 10n ** tokenStore.memeToken.decimals)"
></token-name-price> ></token-name-price>
<token-logo img="/assets/img/vampir.png" :alt="'vampire'"></token-logo> <token-logo img="/assets/img/vampir.png" :size="64" :alt="'vampire'"></token-logo>
</div> </div>
</div> </div>
<div class="claim-button"> <div class="claim-button">
@@ -55,17 +62,34 @@
<button class="btn btn-immortal sub-header" @click="showPanel = true">Connect</button> <button class="btn btn-immortal sub-header" @click="showPanel = true">Connect</button>
</template> </template>
<template v-else-if="activeCycle === currentCycle"> <template v-else-if="activeCycle === currentCycle">
<button class="btn btn-immortal sub-header" @click="router.push({ name: 'home' })">Sacrifice</button> <template v-if="rewardsSacrifice > 0n">
<div class="stake-buttons">
<button class="btn btn-immortal sub-header btn--disabled">Claim</button>
<button class="btn btn-immortal sub-header btn--disabled">Stake</button>
</div>
<div>You can claim once the current cycle is finished and the clan bonus calculated</div>
</template> </template>
<template v-else-if="getCurrentCycleData?.rewards_total > 0"> <template v-else>
<button class="btn btn-immortal sub-header" @click="router.push({ name: 'home' })">
Sacrifice
</button>
</template>
</template>
<template v-else-if="rewardsTotal > 0">
<Transition name="smooth"> <Transition name="smooth">
<div class="stake-buttons" v-show="!stakeMenu"> <div class="stake-buttons" v-show="!stakeMenu">
<div class="btn btn-immortal" v-if="stateClaimedComp === 0" @click="claimRewards">Claim</div> <div class="btn btn-immortal sub-header" v-if="stateClaimedComp === 0" @click="claimRewards">
<div class="btn btn-immortal" disabled v-if="stateClaimedComp === 2">Sign Transaction</div> Claim
<div class="btn btn-immortal" disabled v-if="stateClaimedComp === 3"> </div>
<div class="btn btn-immortal sub-header" disabled v-if="stateClaimedComp === 2">
Sign Transaction
</div>
<div class="btn btn-immortal sub-header" disabled v-if="stateClaimedComp === 3">
<loading-component></loading-component> <loading-component></loading-component>
</div> </div>
<div class="btn btn-immortal" @click="openStake">Stake</div> <div class="btn btn-immortal sub-header" v-if="stateClaimedComp === 0" @click="openStake">
Stake
</div>
</div> </div>
</Transition> </Transition>
<Transition name="smooth"> <Transition name="smooth">
@@ -73,24 +97,36 @@
v-model="tokenNumber" v-model="tokenNumber"
@close="stakeMenu = false" @close="stakeMenu = false"
:stake="stake" :stake="stake"
:amount="getCurrentCycleData?.rewards_total" :amount="rewardsTotal"
v-if="stakeMenu" v-if="stakeMenu"
> >
<template v-slot:body> <template v-slot:body>
<div class="btn btn-immortal stake-button" disabled v-if="stateStakeClaimComp === 0"> <div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 0"
>
Enter Amount Enter Amount
</div> </div>
<div <div
class="btn btn-immortal stake-button" class="btn btn-immortal sub-header stake-button"
v-else-if="stateStakeClaimComp === 1" v-else-if="stateStakeClaimComp === 1"
@click="stakeAndClaim" @click="stakeAndClaim"
> >
Stake & Claim Rest Stake & Claim Rest
</div> </div>
<div class="btn btn-immortal stake-button" disabled v-if="stateStakeClaimComp === 2"> <div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 2"
>
Sign Transaction Sign Transaction
</div> </div>
<div class="btn btn-immortal stake-button" disabled v-if="stateStakeClaimComp === 3"> <div
class="btn btn-immortal sub-header stake-button"
disabled
v-if="stateStakeClaimComp === 3"
>
<loading-component></loading-component> <loading-component></loading-component>
</div> </div>
<div <div
@@ -124,7 +160,7 @@ import { waitForTransaction } from "@wagmi/core";
import LoadingComponent from "@/components/LoadingComponent.vue"; import LoadingComponent from "@/components/LoadingComponent.vue";
import TokenNamePrice from "@/components/TokenNamePrice.vue"; import TokenNamePrice from "@/components/TokenNamePrice.vue";
import TokenLogo from "@/components/TokenLogo.vue"; import TokenLogo from "@/components/TokenLogo.vue";
import { formatNumber } from "@/helper/helper.js"; import { formatNumber, formatBigIntDivision } from "@/helper/helper.js";
import { showSuccessToast } from "@/helper/toast.js"; import { showSuccessToast } from "@/helper/toast.js";
const showPanel = inject("showPanel"); const showPanel = inject("showPanel");
@@ -135,7 +171,8 @@ const tokenStore = useTokenStore();
const cycleStore = useCycleStore(); const cycleStore = useCycleStore();
const router = useRouter(); const router = useRouter();
const { activeCycle, currentCycle, getCurrentCycleData } = storeToRefs(cycleStore); const { activeCycle, currentCycle, getCurrentCycleData, rewardsSacrifice, rewardsStaking, rewardsClan, rewardsTotal } =
storeToRefs(cycleStore);
const stakeMenu = ref(false); const stakeMenu = ref(false);
const stake = ref(null); const stake = ref(null);
@@ -145,13 +182,16 @@ const stateStakeClaim = ref(0);
async function stakeAndClaim() { async function stakeAndClaim() {
try { try {
console.log("stakeAndClaim");
console.log(tokenNumber.value); console.log(tokenNumber.value);
console.log(getCurrentCycleData.value.rewards_total); console.log(rewardsTotal.value);
const coefficient = (10000 * tokenNumber.value) / getCurrentCycleData.value.rewards_total;
stateStakeClaim.value = 2; stateStakeClaim.value = 2;
console.log("hier1");
const coefficient = (10000n * BigInt(tokenNumber.value)) / rewardsTotal.value;
var hash = await rewardLockerStore.stakeAndClaimCycle(coefficient, cycleStore.activeCycle); var hash = await rewardLockerStore.stakeAndClaimCycle(coefficient, cycleStore.activeCycle);
console.log("hash"); console.log("hier2");
stateStakeClaim.value = 3; stateStakeClaim.value = 3;
console.log("hash");
const data = await waitForTransaction({ const data = await waitForTransaction({
hash: hash, hash: hash,
}); });
@@ -171,23 +211,26 @@ async function stakeAndClaim() {
}); });
// //
console.log("rewardData", rewardData); console.log("rewardData", rewardData);
const outputClaim = Number(rewardData?.topics[2]) / Math.pow(10, tokenStore.memeToken.decimals); console.log("stakeData", stakeData);
const outputStaked = Number(stakeData?.topics[3]) / Math.pow(10, tokenStore.memeToken.decimals); const outputClaim = BigInt(rewardData?.topics[2]);
const outputStaked = BigInt(stakeData?.topics[3]);
showSuccessToast( showSuccessToast(
formatNumber(outputClaim + outputStaked), formatNumber(outputClaim + outputStaked, 10n ** tokenStore.memeToken.decimals),
"Success!", "Success!",
"You just claimed and staked", "You just claimed and staked",
"Join the next cycle to increase your rewards and win with your clan." "Join the next cycle to increase your rewards and win with your clan."
); );
tokenNumber.value = 0; tokenNumber.value = 0;
stakeMenu.value = false; stakeMenu.value = false;
await cycleStore.fillCycle(activeCycle.value, true);
await walletStore.loadWalletData(); await walletStore.loadWalletData();
} catch (error) { } catch (error) {
console.error("stakeAndClaim", error); console.error("stakeAndClaim", error);
} finally { } finally {
const walletStore = useWalletStoreV2(); const walletStore = useWalletStoreV2();
await walletStore.loadWalletData(); await walletStore.loadWalletData();
console.log("finally1");
await cycleStore.fillCycle(activeCycle.value, true);
console.log("finally2");
stateStakeClaim.value = 1; stateStakeClaim.value = 1;
} }
} }
@@ -220,9 +263,9 @@ async function claimRewards() {
// //
console.log("rewardData", rewardData); console.log("rewardData", rewardData);
const outputClaim = Number(rewardData.topics[2]) / Math.pow(10, tokenStore.memeToken.decimals); const outputClaim = formatNumber(BigInt(rewardData.topics[2]), 10n ** tokenStore.memeToken.decimals);
showSuccessToast( showSuccessToast(
formatNumber(outputClaim), outputClaim,
"Success!", "Success!",
"You just claimed", "You just claimed",
"Join the next cycle to increase your rewards and win with your clan." "Join the next cycle to increase your rewards and win with your clan."
@@ -236,6 +279,16 @@ async function claimRewards() {
} }
} }
const clanBonusPercentage = computed(() => {
return (
(
(formatBigIntDivision(rewardsClan.value, 10n ** tokenStore.memeToken.decimals, 8) /
formatBigIntDivision(rewardsTotal.value, 10n ** tokenStore.memeToken.decimals, 8)) *
100
).toFixed(2) + "%"
);
});
const stateClaimedComp = computed(() => { const stateClaimedComp = computed(() => {
let returnState = 0; let returnState = 0;
if (stateClaim.value === 2) { if (stateClaim.value === 2) {
@@ -249,19 +302,19 @@ const stateClaimedComp = computed(() => {
const stateStakeClaimComp = computed(() => { const stateStakeClaimComp = computed(() => {
console.log("stateStakeClaimComp"); console.log("stateStakeClaimComp");
let returnState = 0; let returnState = 0;
if ( if (stateStakeClaim.value === 2) {
tokenNumber.value === null ||
tokenNumber.value === "" ||
tokenNumber.value === 0 ||
tokenNumber.value > walletStore.memeToken?.unclaimedRewards
) {
returnState = 0;
} else if (stateStakeClaim.value === 2) {
returnState = 2; returnState = 2;
} else if (stateStakeClaim.value === 3) { } else if (stateStakeClaim.value === 3) {
returnState = 3; returnState = 3;
} else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) { } else if (tokenNumber.value !== null || tokenNumber.value !== "" || tokenNumber.value > 0) {
returnState = 1; returnState = 1;
} else if (
tokenNumber.value === null ||
tokenNumber.value === "" ||
tokenNumber.value === 0 ||
BigInt(tokenNumber.value) > walletStore.unclaimedRewards / 10n ** tokenStore.memeToken.decimals
) {
returnState = 0;
} }
return returnState; return returnState;
}); });
@@ -279,6 +332,9 @@ const stateStakeClaimComp = computed(() => {
text-align: left text-align: left
.claim-button .claim-button
text-align: center text-align: center
display: flex
flex-direction: column
gap: 24px
.stake-buttons .stake-buttons
display: flex display: flex
text-align: center text-align: center
@@ -302,7 +358,6 @@ const stateStakeClaimComp = computed(() => {
justify-content: space-between justify-content: space-between
text-align: left text-align: left
box-sizing: content-box box-sizing: content-box
height: 56px
.rewards-left .rewards-left
display: flex display: flex
flex-direction: column flex-direction: column
+6 -3
View File
@@ -7,6 +7,7 @@
:value="props.modelValue" :value="props.modelValue"
:placeholder="0" :placeholder="0"
type="number" type="number"
pattern="\d*"
/> />
<div class="value-adder"> <div class="value-adder">
<slot class="value-adder" name="message"></slot> <slot class="value-adder" name="message"></slot>
@@ -14,7 +15,7 @@
</div> </div>
</div> </div>
<div class="right-side"> <div class="right-side">
<token-logo :img="props.logo" :alt="'vampir'"></token-logo> <token-logo v-if="props.logo" :img="props.logo" :alt="'vampir'"></token-logo>
</div> </div>
</div> </div>
</div> </div>
@@ -26,7 +27,7 @@ import TokenLogo from "@/components/TokenLogo.vue";
const props = defineProps({ const props = defineProps({
modelValue: [String, Number], modelValue: [String, Number],
logo: String, logo: String,
max: Number, max: [BigInt, Number],
}); });
const emit = defineEmits(["update:modelValue"]); const emit = defineEmits(["update:modelValue"]);
@@ -62,10 +63,12 @@ const emit = defineEmits(["update:modelValue"]);
.stake-adder-step .stake-adder-step
padding: 4px 16px padding: 4px 16px
color: var(--black) color: var(--black)
font-size: 14px font-size: 12px
border-width: 1px border-width: 1px
border-color: transparent border-color: transparent
border-style: solid border-style: solid
@media (min-width: 992px)
font-size: 14px
&:hover,&:active, &:focus &:hover,&:active, &:focus
background-color: var(--grey-light) background-color: var(--grey-light)
cursor: pointer cursor: pointer
+1 -1
View File
@@ -7,7 +7,7 @@
<script setup> <script setup>
const props = defineProps({ const props = defineProps({
img: String, img: String,
alt: Number, alt: String,
size: { size: {
type: Number, type: Number,
default: 45, default: 45,
+9 -2
View File
@@ -1,7 +1,9 @@
<template> <template>
<div class="token-price-wrapper"> <div class="token-price-wrapper">
<div class="token-name small-text">{{ props.name }}</div> <div class="token-name tiny-text">{{ props.name }}</div>
<div class="token-price sub-header">{{ props.price }}</div> <div class="token-price" :class="{ 'sub-header-2': !props.variant, 'sub-header': props.variant }">
{{ props.price }}
</div>
</div> </div>
</template> </template>
@@ -9,6 +11,11 @@
const props = defineProps({ const props = defineProps({
name: String, name: String,
price: [Number, String], price: [Number, String],
variant: {
type: Boolean,
required: false,
default: false,
},
}); });
</script> </script>
+6 -41
View File
@@ -1,29 +1,19 @@
<template> <template>
<div class="approve-card"> <div class="approve-card">
<div class="left-side low-mid-text"> <div class="left-side low-mid-text">Transaction Successful</div>
Transaction<br />
Successful
</div>
<div class="right-side">
<div class="btn btn-immortal tiny-text" v-if="stateComputed === 1" @click="sacrificeClick">
Sacrifice 🩸
</div>
<div class="btn btn-immortal tiny-text" disabled v-if="stateComputed === 2">Sign Transaction</div>
<div class="btn btn-immortal tiny-text" disabled v-if="stateComputed === 3">
<loading-component></loading-component>
</div>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import LoadingComponent from "@/components/LoadingComponent.vue"; import LoadingComponent from "@/components/LoadingComponent.vue";
import { getCurrentInstance, computed, watch } from "vue"; import { getCurrentInstance, computed, watch, inject } from "vue";
import { useTokenStore } from "@/stores/tokens"; import { useTokenStore } from "@/stores/tokens";
import { useSacrificeStore } from "@/stores/sacrifice"; import { useSacrificeStore } from "@/stores/sacrifice";
import CardComponent from "@/components/CardComponent.vue"; import CardComponent from "@/components/CardComponent.vue";
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
const emit = defineEmits(["sacrificed"]);
const props = defineProps({ const props = defineProps({
value: String, value: String,
header: String, header: String,
@@ -37,36 +27,11 @@ const sacrificeStore = useSacrificeStore();
const instance = getCurrentInstance(); const instance = getCurrentInstance();
const id = instance.attrs["toast-id"]; const id = instance.attrs["toast-id"];
const splashBlood = inject("splashBlood");
function closeToast() { function closeToast() {
toast.dismiss(id); toast.dismiss(id);
} }
const stateComputed = computed(() => {
let returnState = 0;
if (
sacrificeStore.sacrificeNumber === null ||
sacrificeStore.sacrificeNumber === "" ||
sacrificeStore.sacrificeNumber === 0
) {
returnState = 0;
} else if (sacrificeStore.sacrificeState === 2) {
returnState = 2;
} else if (sacrificeStore.sacrificeState === 3) {
returnState = 3;
} else if (
sacrificeStore.sacrificeNumber !== null ||
sacrificeStore.sacrificeNumber !== "" ||
sacrificeStore.sacrificeNumber > 0
) {
returnState = 1;
}
return returnState;
});
async function sacrificeClick() {
await sacrificeStore.sacrificeToken(sacrificeStore.sacrificeNumber, tokenStore.activeToken);
closeToast();
}
</script> </script>
<style lang="sass"> <style lang="sass">
.Vue-Toastification__container .Vue-Toastification__container
+1 -1
View File
@@ -10,7 +10,7 @@
</div> </div>
<div class="amount-number"> <div class="amount-number">
<div class="token-amount number-mobile">{{ props.value }}</div> <div class="token-amount number-mobile">{{ props.value }}</div>
<div class="token-name">$Blood</div> <div class="token-name">$BLOOD</div>
</div> </div>
<div class="info toast-body"> <div class="info toast-body">
{{ props.info }} {{ props.info }}
@@ -0,0 +1,86 @@
<template>
<div class="network-switch-card">
<div>Please switch Network to</div>
<div>
<b>{{ props.network.chains[0].name }}</b>
</div>
</div>
</template>
<script setup>
import LoadingComponent from "@/components/LoadingComponent.vue";
import { getCurrentInstance, computed, watch, inject } from "vue";
import { useTokenStore } from "@/stores/tokens";
import { useSacrificeStore } from "@/stores/sacrifice";
import CardComponent from "@/components/CardComponent.vue";
import { useToast } from "vue-toastification";
const emit = defineEmits(["sacrificed"]);
const props = defineProps({
network: Object,
});
const toast = useToast();
const tokenStore = useTokenStore();
const sacrificeStore = useSacrificeStore();
const instance = getCurrentInstance();
const id = instance.attrs["toast-id"];
const splashBlood = inject("splashBlood");
function closeToast() {
toast.dismiss(id);
}
const stateComputed = computed(() => {
let returnState = 0;
if (
sacrificeStore.sacrificeNumber === null ||
sacrificeStore.sacrificeNumber === "" ||
sacrificeStore.sacrificeNumber === 0
) {
returnState = 0;
} else if (sacrificeStore.sacrificeState === 2) {
returnState = 2;
} else if (sacrificeStore.sacrificeState === 3) {
returnState = 3;
} else if (
sacrificeStore.sacrificeNumber !== null ||
sacrificeStore.sacrificeNumber !== "" ||
sacrificeStore.sacrificeNumber > 0
) {
returnState = 1;
}
return returnState;
});
async function sacrificeClick() {
try {
var result = await sacrificeStore.sacrificeToken(sacrificeStore.sacrificeNumber, tokenStore.activeToken);
if (result) {
emit("sacrificed");
}
} catch (error) {
console.error("error", error);
} finally {
closeToast();
}
}
</script>
<style lang="sass">
.Vue-Toastification__container
.Vue-Toastification__toast--default
&.approve-toast
background: transparent
&.toast-card
padding: 24px 16px
border-radius: 10px
border: 2px solid var(--dark-purple, #4B0082)
background: var(--midnight-black, #0F0F0F)
.Vue-Toastification__toast-component-body
.network-switch-card
display: flex
flex-direction: column
display: flex
</style>
+24 -20
View File
@@ -1,31 +1,42 @@
export function getImageUrl(url) {
return new URL(url, import.meta.url).href;
}
export function getPercentage(amount, goal) { export function getPercentage(amount, goal) {
return ((Number(amount) / Number(goal)) * 100).toFixed(2); return ((Number(amount) / Number(goal)) * 100).toFixed(2);
} }
export function compactNumber(number) { export function compactNumber(number) {
return Intl.NumberFormat("en-US", { return Intl.NumberFormat("en-US", {
notation: "compact", notation: "compact",
maximumFractionDigits: 2, maximumFractionDigits: 2,
}).format(parseInt(number)); }).format(number);
} }
export function formatNumber(number) { export function formatNumber(nominator, denominator) {
const options = { let number = formatBigIntDivision(nominator, denominator);
style: "decimal", number = InsertCommaNumber(number).toString();
minimumFractionDigits: 0,
maximumFractionDigits: 0, return number;
}; }
export function formatBigIntDivision(nominator, denominator, digits = 2) {
console.log("nominator", nominator);
console.log("denominator", denominator);
if (!nominator) {
return 0n
}
let integer = Number(nominator / denominator);
// pick how much digits after point to show
const fraction = (nominator % denominator).toString().substring(0, digits);
// output type number
return Number(integer + "." + fraction);
}
export function InsertCommaNumber(number) {
if (!number) { if (!number) {
return 0 return 0
} }
const formattedWithOptions = number.toLocaleString("en-US", options); const formattedWithOptions = number.toLocaleString("en-US");
return formattedWithOptions; return formattedWithOptions;
} }
@@ -37,13 +48,6 @@ export function getAddressShortName(address) {
} }
export function numberWithCommas(x, ) {
x = x.toString();
var pattern = /(-?\d+)(\d{3})/;
while (pattern.test(x)) x = x.replace(pattern, "$1,$2");
return x;
}
export function getblocky(address) { export function getblocky(address) {
var blockiesData = blockies var blockiesData = blockies
.create({ .create({
+70 -8
View File
@@ -38,13 +38,15 @@ import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
/* import specific icons */ /* import specific icons */
import { faArrowDown, faArrowRight, faSpinner, faPlus, faCaretLeft, faCaretRight, faBars, faAnglesRight, faChevronDown, faChevronUp, faArrowRightToBracket, faArrowRightFromBracket, faDroplet, faMoon, faPerson } from "@fortawesome/free-solid-svg-icons"; import { faArrowDown, faArrowRight, faSpinner, faPlus, faCaretLeft, faCaretRight, faBars, faAnglesRight, faChevronDown, faChevronUp, faArrowRightToBracket, faArrowRightFromBracket, faDroplet, faMoon, faPerson, faWallet, faBlog } from "@fortawesome/free-solid-svg-icons";
import { faDiscord, faTwitter, faTelegram } from "@fortawesome/free-brands-svg-icons"; import { faDiscord, faTwitter, faTelegram } from "@fortawesome/free-brands-svg-icons";
import Toast from "vue-toastification"; import Toast from "vue-toastification";
// Import the CSS or use your own! // Import the CSS or use your own!
import "vue-toastification/dist/index.css"; import "vue-toastification/dist/index.css";
import SwitchNetworkToast from "@/components/toasts/SwitchNetworkToast.vue";
import { useToast } from "vue-toastification";
/* add icons to the library */ /* add icons to the library */
library.add( library.add(
@@ -65,9 +67,21 @@ library.add(
faChevronUp, faChevronUp,
faDroplet, faDroplet,
faMoon, faMoon,
faPerson faPerson,
faWallet,
faBlog
); );
var logging = localStorage.getItem("LOGGING");
if (logging === "true") {
} else {
if (!window.console) window.console = {};
var methods = ["log", "debug", "warn", "info"];
for (let i = 0; i < methods.length; i++) {
console[methods[i]] = function () {};
}
}
const app = createApp(App) const app = createApp(App)
@@ -80,9 +94,39 @@ app.use(pinia);
app.use(Toast, { app.use(Toast, {
transition: "Vue-Toastification__fade", transition: "Vue-Toastification__fade",
containerClassName: "bloodline-toast-container",
}); });
function showSwitchNetworkToast(network) {
const toast = useToast();
// Define the content object with the component, props and listeners
const content = {
component: SwitchNetworkToast,
// Any prop can be passed, but don't expect them to be reactive
props: {
network
},
// Listen and react to events using callbacks. In this case we listen for
// the "click" event emitted when clicking the toast button
listeners: {},
};
// Render the toast and its contents
return toast(content, {
position: "top-right",
icon: false,
closeOnClick: false,
// toastClassName: "modal-overlay",
hideProgressBar: true,
timeout: false,
toastClassName: "approve-toast toast-card",
});
}
try { try {
const walletStore = useWalletStoreV2(); const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
@@ -95,7 +139,8 @@ try {
const projectId = "d8e5ecb0353c02e21d4c0867d4473ac5"; const projectId = "d8e5ecb0353c02e21d4c0867d4473ac5";
console.log("hier chains"); console.log("hier chains");
const { chains, publicClient, webSocketPublicClient } = configureChains( const { chains, publicClient, webSocketPublicClient } = configureChains(
[goerli, mainnet], // [goerli, mainnet],
[goerli],
[alchemyProvider({ apiKey: goerliKey }), publicProvider()] [alchemyProvider({ apiKey: goerliKey }), publicProvider()]
); );
@@ -108,8 +153,11 @@ try {
appName: "wagmi demo", appName: "wagmi demo",
}, },
}), }),
new MetaMaskConnector({ chains }), // new MetaMaskConnector({ chains }),
// new InjectedConnector({ chains }), new InjectedConnector({
chains,
getProvider: () => (typeof window !== "undefined" ? window.myInjectedWallet : undefined),
}),
new WalletConnectConnector({ new WalletConnectConnector({
chains, chains,
options: { options: {
@@ -150,9 +198,9 @@ try {
}, },
async (log) => { async (log) => {
console.log("CycleCompleted", log); console.log("CycleCompleted", log);
await cycleStore.fillCycle(cycleStore.currentCycle); await cycleStore.fillCycle(cycleStore.currentCycle, true);
cycleStore.currentCycle++; cycleStore.currentCycle++;
await cycleStore.fillCycle(cycleStore.currentCycle); await cycleStore.fillCycle(cycleStore.currentCycle, true);
} }
); );
@@ -179,7 +227,7 @@ try {
await tokenStore.initV2(); await tokenStore.initV2();
await rewardLockerStore.init(); await rewardLockerStore.init();
await walletStore.loadWalletData(); await walletStore.loadWalletData();
await cycleStore.fillCycle(cycleStore.currentCycle); await cycleStore.fillCycle(cycleStore.currentCycle, true);
await uniswapStore.init(); await uniswapStore.init();
} else { } else {
walletStore.address = null; walletStore.address = null;
@@ -189,12 +237,26 @@ try {
}); });
watchNetwork((network) => { watchNetwork((network) => {
if (!network.chain?.network) {
return;
}
const chainAllowed = network.chains?.find((obj) => {
return obj.network === network.chain.network;
});
if (!chainAllowed) {
console.log("chain not allowed", network.chain);
showSwitchNetworkToast(network);
return
} else {
console.log("chain allowed", network.chain);
}
if (network.chain) { if (network.chain) {
walletStore.chain = network.chain; walletStore.chain = network.chain;
} }
}); });
await walletStore.init(); await walletStore.init();
await tokenStore.initV2(); await tokenStore.initV2();
await memeBurnerStore.init(); await memeBurnerStore.init();
+78 -39
View File
@@ -30,6 +30,43 @@ export const useCycleStore = defineStore("cycles", {
getCurrentCycleData() { getCurrentCycleData() {
return this.cycles[this.activeCycle]; return this.cycles[this.activeCycle];
}, },
rewardsSacrifice() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_sacrifice) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_sacrifice;
},
rewardsSacrificeCurrentCycle() {
const tokenStore = useTokenStore();
if (!this.cycles[this.currentCycle]?.rewards_sacrifice) {
return 0n;
}
return this.cycles[this.currentCycle]?.rewards_sacrifice;
},
rewardsStaking() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_staking) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_staking;
},
rewardsClan() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_clan) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_clan;
},
rewardsTotal() {
const tokenStore = useTokenStore();
if (!this.cycles[this.activeCycle]?.rewards_total) {
return 0n;
}
return this.cycles[this.activeCycle]?.rewards_total;
},
}, },
actions: { actions: {
//todo check if still needed //todo check if still needed
@@ -62,25 +99,26 @@ export const useCycleStore = defineStore("cycles", {
//todo check if needed, or use fillcycle //todo check if needed, or use fillcycle
async updateCurrentCycle(sacrificedToken) { async updateCurrentCycle(sacrificedToken) {
console.log("updateCurrentCycle"); console.log("updateCurrentCycle");
const tokenStore = useTokenStore();
const memeBurnerStore = useMemeburnerStore(); const memeBurnerStore = useMemeburnerStore();
const rewardLockerStore = useRewardLockerStore();
var data = await memeBurnerStore.getSacrificedCycle(this.currentCycle); var data = await memeBurnerStore.getSacrificedCycle(this.currentCycle);
var tokenTotalSacrificed = await rewardLockerStore.getTotalSacrificeRewardsForAllToken(this.currentCycle);
console.log("this.currentCycle", this.currentCycle); console.log("this.currentCycle", this.currentCycle);
console.log("this.cycles", this.cycles); console.log("this.cycles", this.cycles);
var tokenIndex = this.cycles[this.currentCycle]?.token.findIndex( if (this.cycles[this.currentCycle]) {
var tokenIndex = this.cycles[this.currentCycle].token.findIndex(
(tokenData) => tokenData.contractAddress === sacrificedToken (tokenData) => tokenData.contractAddress === sacrificedToken
); );
console.log("tokenIndex", tokenIndex); this.cycles[this.currentCycle].token[tokenIndex].amount = data[tokenIndex].result[1];
const token = tokenStore.getToken(sacrificedToken); this.cycles[this.currentCycle].token[tokenIndex].amountInBLD = tokenTotalSacrificed[tokenIndex].result;
this.cycles[this.currentCycle].token[tokenIndex].amount = }
Number(data[tokenIndex].result[1]) / Math.pow(10, token.decimals)
}, },
/** /**
* main function to fill a round, will not be filled when already loaded * main function to fill a round, will not be filled when already loaded
* you can use the refillcycle to overwrite information, because if you claim or stake the values will change * you can use the refillcycle to overwrite information, because if you claim or stake the values will change
*/ */
async fillCycle(cycleNumber, refillCycle = false) { async fillCycle(cycleNumber, refillCycle = false) {
console.log("fillCycle"); console.log("fillCycle", cycleNumber);
const memeBurnerStore = useMemeburnerStore(); const memeBurnerStore = useMemeburnerStore();
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const walletStore = useWalletStoreV2(); const walletStore = useWalletStoreV2();
@@ -97,14 +135,18 @@ export const useCycleStore = defineStore("cycles", {
rewardData = await rewardLockerStore.getRewardsForAllToken(cycleNumber); rewardData = await rewardLockerStore.getRewardsForAllToken(cycleNumber);
} }
console.log("hier");
//getTotalSacrificeRewardsForToken multicall for all tokens //getTotalSacrificeRewardsForToken multicall for all tokens
const tokenTotalSacrificed = await rewardLockerStore.getTotalSacrificeRewardsForAllToken(cycleNumber); const tokenTotalSacrificed = await rewardLockerStore.getTotalSacrificeRewardsForAllToken(cycleNumber);
console.log("hier1");
var goal = await memeBurnerStore.getGoal(cycleNumber); var goal = await memeBurnerStore.getGoal(cycleNumber);
console.log("hier123");
var tokenArray = []; var tokenArray = [];
var rewards_clan = 0; var rewards_clan = 0n;
var rewards_sacrifice = 0; var rewards_sacrifice = 0n;
var rewards_staking = 0; var rewards_staking = 0n;
console.log("hier123");
for (let index = 0; index < data.length; index++) { for (let index = 0; index < data.length; index++) {
var tokenData = {}; var tokenData = {};
const token = tokenStore.token[index]; const token = tokenStore.token[index];
@@ -114,61 +156,57 @@ export const useCycleStore = defineStore("cycles", {
token.contractAddress token.contractAddress
); );
console.log("coefficent", coefficent); console.log("coefficent", coefficent);
tokenData.name = token.name; tokenData.name = token.name;
tokenData.contractAddress = token.contractAddress; tokenData.contractAddress = token.contractAddress;
tokenData.vamplogo = token.vamp.logo; tokenData.vamplogo = token.vamp.logo;
tokenData.vampwinner = token.vamp.winner; tokenData.vampwinner = token.vamp.winner;
tokenData.vampwinner2 = token.vamp.winner2; tokenData.vampwinner2 = token.vamp.winner2;
tokenData.vampname = token.vamp.name; tokenData.vampname = token.vamp.name;
tokenData.amount = Number(data[index].result[1]) / Math.pow(10, token.decimals); tokenData.amount = data[index].result[1];
tokenData.amountInBLD = Number(tokenTotalSacrificed[index].result) / Math.pow(10, token.decimals); tokenData.amountInBLD = tokenTotalSacrificed[index].result;
if (walletStore.connected) { if (walletStore.connected) {
//if user is connected fill user specific data for the token //if user is connected fill user specific data for the token
const sacrificeClanReward = Number(rewardData[index].result[1]); const sacrificeClanReward = rewardData[index].result[1];
let clanwin = 0; let clanwin = 0n;
if (cycleNumber !== this.currentCycle) { if (cycleNumber !== this.currentCycle) {
clanwin = (Number(coefficent) / 10000 - 1) * sacrificeClanReward; clanwin = (sacrificeClanReward * coefficent) / 10000n - sacrificeClanReward;
console.log("clanwin", clanwin); console.log("clanwin", clanwin);
} }
const sacrificeRewards = Number(sacrificeClanReward); const sacrificeRewards = sacrificeClanReward;
tokenData.rewards_ges = Number( tokenData.rewards_ges = rewardData[index].result[1] + rewardData[index].result[0];
rewardData[index].result[1] / BigInt(Math.pow(10, token.decimals)) +
rewardData[index].result[0] / BigInt(Math.pow(10, token.decimals))
);
tokenData.rewards_clan = clanwin / Math.pow(10, token.decimals); tokenData.rewards_clan = clanwin;
tokenData.rewards_staking = Number( tokenData.rewards_staking = rewardData[index].result[0];
rewardData[index].result[0] / BigInt(Math.pow(10, token.decimals)) tokenData.rewards_sacrifice = sacrificeRewards;
);
tokenData.rewards_sacrifice = sacrificeRewards / Math.pow(10, token.decimals);
console.log("rewards_clan", rewards_clan);
console.log("tokenData.rewards_clan", tokenData.rewards_clan);
console.log("tokenData.rewards_sacrifice", tokenData.rewards_sacrifice);
rewards_clan = rewards_clan + tokenData.rewards_clan; rewards_clan = rewards_clan + tokenData.rewards_clan;
rewards_sacrifice = rewards_sacrifice + tokenData.rewards_sacrifice; rewards_sacrifice = rewards_sacrifice + tokenData.rewards_sacrifice;
rewards_staking = rewards_staking + tokenData.rewards_staking; rewards_staking = rewards_staking + tokenData.rewards_staking;
} }
tokenArray.push(tokenData); tokenArray.push(tokenData);
} }
const goalDecimal = Number(goal[0]) / Math.pow(10, tokenStore.memeToken.decimals); const goalDecimal = goal[0];
const winner = tokenArray.find((token) => token.amount === goalDecimal); const winner = tokenArray.find((token) => token.amount === goalDecimal);
const goalInBLD = await memeBurnerStore.getGoalInBLOOD(cycleNumber); const goalInBLD = await memeBurnerStore.getGoalInBLOOD(cycleNumber);
//replace vamplogo cause it will automatically change the token for the cycle view (new design) //replace vamplogo cause it will automatically change the token for the cycle view (new design)
if (winner) { // if (winner) {
winner.vamplogo = winner.vampwinner; // winner.vamplogo = winner.vampwinner;
} // }
this.cycles[cycleNumber] = { this.cycles[cycleNumber] = {
goal: Number(goal[0]) / Math.pow(10, tokenStore.memeToken.decimals), goal: goal[0],
goalInBLD: Number(goalInBLD / BigInt(Math.pow(10, tokenStore.memeToken.decimals))), goalInBLD: goalInBLD,
expirationTimestamp: Number(goal[2]), expirationTimestamp: goal[2],
rewards_clan: Number(rewards_clan), rewards_clan: rewards_clan,
rewards_staking: Number(rewards_staking), rewards_staking: rewards_staking,
rewards_sacrifice: Number(rewards_sacrifice), rewards_sacrifice: rewards_sacrifice,
rewards_total: Number(rewards_clan) + Number(rewards_sacrifice) + Number(rewards_staking), rewards_total: rewards_clan + rewards_sacrifice + rewards_staking,
token: tokenArray, token: tokenArray,
connected: walletStore.connected, connected: walletStore.connected,
winner: winner, winner: winner,
@@ -182,9 +220,10 @@ export const useCycleStore = defineStore("cycles", {
const array = []; const array = [];
const rewardLockerStore = useRewardLockerStore(); const rewardLockerStore = useRewardLockerStore();
const lastCompletedCycle = await rewardLockerStore.lastCompletedCycle(); const lastCompletedCycle = await rewardLockerStore.lastCompletedCycle();
for (let index = 0; index <= Number(lastCompletedCycle); index++) { for (let index = 1; index <= Number(lastCompletedCycle); index++) {
array.push(index); array.push(index);
} }
console.log("array123", array);
return array; return array;
}, },
}, },
+6 -7
View File
@@ -41,6 +41,7 @@ export const useMemeburnerStore = defineStore("memeburner", {
return await this.contract.read.currentCycle(); return await this.contract.read.currentCycle();
}, },
async getGoal(cycleNumber) { async getGoal(cycleNumber) {
console.log("hier123", cycleNumber);
return await this.contract.read.cycles([cycleNumber]); return await this.contract.read.cycles([cycleNumber]);
}, },
//returns participated, amount achieved //returns participated, amount achieved
@@ -79,12 +80,11 @@ export const useMemeburnerStore = defineStore("memeburner", {
return; return;
} }
this.loading = true; this.loading = true;
// TODO: store all integer values as one type: BigInt
const amountDecimal = BigInt(amount) * 10n ** BigInt(tokenStore.activeToken.decimals);
var hash = await this.contract.write.sacrificeMeme([ var hash = await this.contract.write.sacrificeMeme([
tokenStore.activeToken.contractAddress, tokenStore.activeToken.contractAddress,
amountDecimal.toString(), amount,
minETH.toString() minETH
]); ]);
return hash; return hash;
} catch (error) { } catch (error) {
@@ -97,11 +97,10 @@ export const useMemeburnerStore = defineStore("memeburner", {
async sacrificeMemeAndBuyBLOOD(amount, minBLOOD) { async sacrificeMemeAndBuyBLOOD(amount, minBLOOD) {
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const amountDecimal = BigInt(amount) * 10n ** BigInt(tokenStore.activeToken.decimals);
var hash = await this.contract.write.sacrificeMemeAndBuyBLOOD([ var hash = await this.contract.write.sacrificeMemeAndBuyBLOOD([
tokenStore.activeToken.contractAddress, tokenStore.activeToken.contractAddress,
amountDecimal.toString(), amount,
minBLOOD.toString() minBLOOD,
]); ]);
return hash; return hash;
}, },
+32 -12
View File
@@ -32,7 +32,7 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
*/ */
async getRewards(walletAddress, cycleNumber, tokenAddress) { async getRewards(walletAddress, cycleNumber, tokenAddress) {
try { try {
return await this.contract.read.rewards([walletAddress, cycleNumber, tokenAddress]); return await this.contract.read.getRewards([walletAddress, cycleNumber, tokenAddress]);
} catch (error) { } catch (error) {
console.error("getRewards", error); console.error("getRewards", error);
} }
@@ -88,7 +88,6 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
sacrificedToken, sacrificedToken,
reward, reward,
]); ]);
}, },
async lastCompletedCycle() { async lastCompletedCycle() {
return await this.contract.read.lastCompletedCycle(); return await this.contract.read.lastCompletedCycle();
@@ -120,8 +119,15 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
async orderUnstake() { async orderUnstake() {
return await this.contract.write.orderUnstake(); return await this.contract.write.orderUnstake();
}, },
async unstake(unstakeCycle) { async unstake() {
return await this.contract.write.unstake([unstakeCycle]); const walletStore = useWalletStoreV2();
const cycleStore = useCycleStore();
var cycleList = walletStore.memeToken.orderedUnstakedCycles.findIndex((obj) => obj.result > 0n);
if (cycleList && cycleList + 1 <= cycleStore.currentCycle) {
console.log("cycleList", cycleList);
const hash = await this.contract.write.unstake([cycleList + 1]);
return hash;
}
}, },
async stakeBloodline(tokenNumber) { async stakeBloodline(tokenNumber) {
console.log("tokenNumber", tokenNumber); console.log("tokenNumber", tokenNumber);
@@ -130,9 +136,9 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
const fromAddress = walletStore.address; const fromAddress = walletStore.address;
const spender = this.config.contractAddress; const spender = this.config.contractAddress;
const deadline = Date.now() + 20 * 60; const deadline = BigInt(Date.now()) / 1000n + 1200n;
const decimals = tokenStore.getToken(walletStore.memeToken.contractAddress).decimals; const decimals = tokenStore.getToken(walletStore.memeToken.contractAddress).decimals;
const value = BigInt(tokenNumber * Math.pow(10, decimals)); const value = BigInt(tokenNumber) * 10n ** decimals;
const nonce = await tokenStore.memeToken.contract.read.nonces([fromAddress]); const nonce = await tokenStore.memeToken.contract.read.nonces([fromAddress]);
console.log("nonce", nonce); console.log("nonce", nonce);
const { types, message, domain, primaryType } = createPermitObject( const { types, message, domain, primaryType } = createPermitObject(
@@ -160,20 +166,34 @@ export const useRewardLockerStore = defineStore("rewardlocker", {
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const addresses = tokenStore.sacrificeToken.map((obj) => obj.contractAddress); const addresses = tokenStore.sacrificeToken.map((obj) => obj.contractAddress);
const hash = await this.contract.write.stakeAndClaim([stakeCoefficient, [cycle], addresses]); const hash = await this.contract.write.stakeAndClaim([stakeCoefficient, [cycle], addresses]);
const data = await waitForTransaction({
hash: hash,
});
return hash; return hash;
}, },
async stakeAndClaimAllCycles(stakeCoefficient) { async stakeAndClaimAllCycles(stakeCoefficient) {
console.log("stakeAndClaimAllCycles"); console.log("stakeAndClaimAllCycles", stakeCoefficient);
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const cycleStore = useCycleStore(); const cycleStore = useCycleStore();
const cycles = await cycleStore.getFinshedCycleNumbers(); const cycles = await cycleStore.getFinshedCycleNumbers();
const addresses = tokenStore.sacrificeToken.map((obj) => obj.contractAddress); const addresses = tokenStore.sacrificeToken.map((obj) => obj.contractAddress);
var stakeCoefficientInt = Math.round(stakeCoefficient); const hash = await this.contract.write.stakeAndClaim([stakeCoefficient, cycles, addresses]);
const hash = await this.contract.write.stakeAndClaim([stakeCoefficientInt, cycles, addresses]);
return hash; return hash;
}, },
async unstakeOrdered() {
const cycleStore = useCycleStore();
const walletStore = useWalletStoreV2();
const contracts = [];
for (let index = 1; index < cycleStore.currentCycle + 2; index++) {
contracts.push({
...this.contract,
functionName: "unstakeOrdered",
args: [index, walletStore.address],
});
}
const data = await multicall({
contracts,
});
console.log("data123", data);
return data;
},
}, },
}); });
+53 -42
View File
@@ -20,12 +20,12 @@ export const useSacrificeStore = defineStore("sacrifice", {
actions: { actions: {
async sacrificeToken(amount, token) { async sacrificeToken(amount, token) {
console.log("sacrificeToken", { amount, token }); console.log("sacrificeToken", { amount, token });
const memeburnerStore = useMemeburnerStore(); const memeburnerStore = useMemeburnerStore();
const walletStore = useWalletStoreV2(); const walletStore = useWalletStoreV2();
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const cycleStore = useCycleStore(); const cycleStore = useCycleStore();
try { try {
this.sacrificeState = 2; this.sacrificeState = 2;
const getRewards = await this.getRewardsFor(amount, token); const getRewards = await this.getRewardsFor(amount, token);
@@ -55,27 +55,30 @@ export const useSacrificeStore = defineStore("sacrifice", {
// }); // });
var rewardData = data.logs.filter((logObject) => { var rewardData = data.logs.filter((logObject) => {
return logObject.topics.filter( return logObject.topics.find(
(topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee" (topic) => topic === "0x5e60ccd3c81486143d815dce24867a494d7fee585a0a44282cf479b19a5186ee"
); );
}); });
console.log("rewardData", rewardData); console.log("rewardData", rewardData);
const outputSacrifice = rewardData.reduce((x, y) => { //output
return x + Number(y.data) / Math.pow(10, token.decimals); let outputSacrifice = rewardData.reduce((x, y) => {
}, 0); return x + BigInt(y.data);
}, 0n);
outputSacrifice = formatNumber(outputSacrifice, 10n ** token.decimals);
console.log("outputSacrifice", outputSacrifice); console.log("outputSacrifice", outputSacrifice);
// const outputSacrifice = Number(rewardData.data) / Math.pow(10, token.decimals);
token.allowance = await tokenStore.allowance(); token.allowance = await tokenStore.allowance();
this.sacrificeState = 4; this.sacrificeState = 4;
showSuccessToast( showSuccessToast(
formatNumber(outputSacrifice), outputSacrifice,
"Success!", "Success!",
"You turned your meme into:", "You turned your meme into:",
"You can claim once the current cycle is finished and your clan bonus was calculated." "You can claim once the current cycle is finished and your clan bonus was calculated."
); );
await walletStore.loadWalletData(); await walletStore.loadWalletData();
console.log("cycleStore.currentCycle", cycleStore.currentCycle);
await cycleStore.fillCycle(cycleStore.currentCycle, true); await cycleStore.fillCycle(cycleStore.currentCycle, true);
return; return true;
} catch (error) { } catch (error) {
//we should show the user an issue //we should show the user an issue
throw new Error(error); throw new Error(error);
@@ -83,38 +86,40 @@ export const useSacrificeStore = defineStore("sacrifice", {
this.sacrificeState = 0; this.sacrificeState = 0;
} }
}, },
async getRewardsFor(value, token) { async getRewardsFor(amount, token) {
console.log("getRewardsFor", {value, token}); console.log("getRewardsFor", { amount, token });
const memeburnerStore = useMemeburnerStore(); const memeburnerStore = useMemeburnerStore();
const uniswapStore = useUniswapStore(); const uniswapStore = useUniswapStore();
const walletStore = useWalletStoreV2(); const walletStore = useWalletStoreV2();
const rewardLockerStore = useRewardLockerStore(); const rewardLockerStore = useRewardLockerStore();
// what is value here? i thought amount and value are same let output = 0n;
const amountDecimal = BigInt(value) * 10n ** BigInt(token.decimals == undefined ? 18n : token.decimals);
let output = 0;
const amountETHBase = await memeburnerStore.getAmountETHBase(amountDecimal);
// take 99.5% of amount ETH got for selling meme, 0.5% allowed slippage
const minETH = amountETHBase[1] * 995n / 1000n;
let minBLOOD; let minBLOOD;
try { try {
if (!value || isNaN(value)) { if (!amount) {
this.sacrificeState = 0; this.sacrificeState = 0;
return output; return {
output: 0n,
};
} }
const amountETHBase = await memeburnerStore.getAmountETHBase(amount);
// take 99.5% of amount ETH got for selling meme, 0.5% allowed slippage
const minETH = (amountETHBase[1] * 995n) / 1000n;
const rewardsForResult = await memeburnerStore.getRewardFor(amountDecimal); const rewardsForResult = await memeburnerStore.getRewardFor(amount);
const rewardsForResultSum = rewardsForResult[0] + rewardsForResult[1]; const rewardsForResultSum = rewardsForResult[0] + rewardsForResult[1];
// quote blood amount against ETH base amount // quote blood amount against ETH base amount
var quoteRewards = await uniswapStore.quoteExactInputSingle(amountDecimal, amountETHBase[0]); var quoteRewards = await uniswapStore.quoteExactInputSingle(amountETHBase[0]);
let variant = "sacrifice"; let variant = "sacrifice";
// here you are setting only variant, let's show by default rewardsForResultSum
output = rewardsForResultSum;
if (quoteRewards.result) { if (quoteRewards.result) {
// take 99.5% of quoted amount, 0.5% allowed slippage // take 99.5% of quoted amount, 0.5% allowed slippage
minBLOOD = quoteRewards.amount * 995n / 1000n; minBLOOD = (quoteRewards.amount * 995n) / 1000n;
if (quoteRewards.amount * 95n / 100n > rewardsForResultSum) { if ((quoteRewards.amount * 95n) / 100n > rewardsForResultSum) {
variant = "buy"; variant = "buy";
console.log("use Buy-function", { console.log("use Buy-function", {
quoteRewardsNumber: quoteRewards.amount, quoteRewardsNumber: quoteRewards.amount,
@@ -126,18 +131,10 @@ export const useSacrificeStore = defineStore("sacrifice", {
rewardsForResultSum, rewardsForResultSum,
}); });
} }
} else {
/**
* case 4
* quoter threw an error
*/
//
output = rewardsForResultSum;
} }
console.log("variant", variant); console.log("variant", variant);
console.log("amountDecimal", amountDecimal); console.log("amount", amount);
// TODO: when token.allowance become BigInt with decimals, value must be amountDecimal if (!walletStore.connected || (walletStore.connected && token.allowance < amount)) {
if (!walletStore.connected || (walletStore.connected && token.allowance < value)) {
/** /**
* case 1 * case 1
* user is not logged in or Allowance is less than Input, then I show getRewardsForSacrifice Value * user is not logged in or Allowance is less than Input, then I show getRewardsForSacrifice Value
@@ -145,15 +142,23 @@ export const useSacrificeStore = defineStore("sacrifice", {
*/ */
output = rewardsForResultSum; output = rewardsForResultSum;
if (variant === "buy") { if (variant === "buy") {
output = quoteRewards.amount output = quoteRewards.amount;
} }
} else if (walletStore.connected && variant === "sacrifice") { } else if (walletStore.connected && variant === "sacrifice" && token.allowance >= amount) {
/** /**
* case 2 * case 2
* user is logged in and allowance is greater or equal input and variant is sacrifice * user is logged in and allowance is greater or equal input and variant is sacrifice
*/ */
output = rewardsForResultSum; // in this case you should use eth_call, so you are showing exact reward in cases of completing cycles
} else if (walletStore.connected && variant === "buy") { const amountSacrifice = await readContract({
address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi,
functionName: "sacrificeMeme",
args: [token.contractAddress, amount.toString(), minETH.toString()],
account: walletStore.address,
});
output = amountSacrifice;
} else if (walletStore.connected && variant === "buy" && token.allowance >= amount) {
/** /**
* case 3 * case 3
* user is logged in and allowance is greater or equal input and variant is buy * user is logged in and allowance is greater or equal input and variant is buy
@@ -163,7 +168,7 @@ export const useSacrificeStore = defineStore("sacrifice", {
address: memeburnerStore.contract.address, address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi, abi: memeburnerStore.contract.abi,
functionName: "sacrificeMeme", functionName: "sacrificeMeme",
args: [token.contractAddress, amountDecimal.toString(), minETH.toString()], args: [token.contractAddress, amount.toString(), minETH.toString()],
account: walletStore.address, account: walletStore.address,
}); });
@@ -171,11 +176,11 @@ export const useSacrificeStore = defineStore("sacrifice", {
address: memeburnerStore.contract.address, address: memeburnerStore.contract.address,
abi: memeburnerStore.contract.abi, abi: memeburnerStore.contract.abi,
functionName: "sacrificeMemeAndBuyBLOOD", functionName: "sacrificeMemeAndBuyBLOOD",
args: [token.contractAddress, amountDecimal.toString(), minBLOOD.toString()], args: [token.contractAddress, amount.toString(), minBLOOD.toString()],
account: walletStore.address, account: walletStore.address,
}); });
if (amountBuy * 95n / 100n > amountSacrifice) { if ((amountBuy * 95n) / 100n > amountSacrifice) {
variant = "buy"; variant = "buy";
output = amountBuy; output = amountBuy;
console.log("use buy after comparison sacrificeMemeAndBuyBLOOD and sacrificeMeme"); console.log("use buy after comparison sacrificeMemeAndBuyBLOOD and sacrificeMeme");
@@ -187,14 +192,20 @@ export const useSacrificeStore = defineStore("sacrifice", {
} }
//potential staking rewards //potential staking rewards
let stakingRewardsNumber = 0; let stakingRewardsNumber = 0;
if (output > 0n && walletStore.connected) { if (output > 0 && walletStore.connected) {
const stakingReward = await rewardLockerStore.getStakeRewardForSacrificeReward( const stakingReward = await rewardLockerStore.getStakeRewardForSacrificeReward(
token.contractAddress, token.contractAddress,
output output
); );
stakingRewardsNumber = (Number(stakingReward / 10n ** BigInt(token.decimals))).toFixed(2); stakingRewardsNumber = stakingReward;
} }
return { output: output, variant: variant, minETH: minETH, minBLOOD: minBLOOD, staking: stakingRewardsNumber }; return {
output: output,
variant: variant,
minETH: minETH,
minBLOOD: minBLOOD,
staking: stakingRewardsNumber,
};
} catch (error) { } catch (error) {
console.error("getRewardsFor", error); console.error("getRewardsFor", error);
} }
+49 -8
View File
@@ -28,6 +28,20 @@ export const useTokenStore = defineStore("token", {
backgroundColor: "#4b8501", backgroundColor: "#4b8501",
abi: Meme1Json.abi, abi: Meme1Json.abi,
contractAddress: Meme1Json.contractAddress, contractAddress: Meme1Json.contractAddress,
addSteps: [
{
amount: 10000000000000000000000000n,
name: "10m",
},
{
amount: 100000000000000000000000000n,
name: "100m",
},
{
amount: 1000000000000000000000000000n,
name: "1b",
},
],
}, },
{ {
name: "$SHIB", name: "$SHIB",
@@ -41,6 +55,20 @@ export const useTokenStore = defineStore("token", {
}, },
abi: Meme2Json.abi, abi: Meme2Json.abi,
contractAddress: Meme2Json.contractAddress, contractAddress: Meme2Json.contractAddress,
addSteps: [
{
amount: 1000000000000000000000000n,
name: "1m",
},
{
amount: 10000000000000000000000000n,
name: "10m",
},
{
amount: 100000000000000000000000000n,
name: "100m",
},
],
}, },
{ {
name: "$ELON", name: "$ELON",
@@ -54,6 +82,20 @@ export const useTokenStore = defineStore("token", {
}, },
abi: Meme3Json.abi, abi: Meme3Json.abi,
contractAddress: Meme3Json.contractAddress, contractAddress: Meme3Json.contractAddress,
addSteps: [
{
amount: 10000000000000000000000000n,
name: "10m",
},
{
amount: 100000000000000000000000000n,
name: "100m",
},
{
amount: 1000000000000000000000000000n,
name: "1b",
},
],
}, },
// { // {
// name: "$BITCOIN", // name: "$BITCOIN",
@@ -80,6 +122,7 @@ export const useTokenStore = defineStore("token", {
// contractAddress: Meme5Json.contractAddress, // contractAddress: Meme5Json.contractAddress,
// }, // },
{ {
name: "$BLOOD",
abi: BloodlineJson.abi, abi: BloodlineJson.abi,
contractAddress: BloodlineJson.contractAddress, contractAddress: BloodlineJson.contractAddress,
logo: "/assets/img/token/bloodline.png", logo: "/assets/img/token/bloodline.png",
@@ -119,16 +162,16 @@ export const useTokenStore = defineStore("token", {
}); });
contracts.push({ ...token.contract, functionName: "decimals" }); contracts.push({ ...token.contract, functionName: "decimals" });
contracts.push({ ...token.contract, functionName: "name" }); // contracts.push({ ...token.contract, functionName: "name" });
contracts.push({ ...token.contract, functionName: "symbol" }); contracts.push({ ...token.contract, functionName: "symbol" });
contracts.push({ ...token.contract, functionName: "totalSupply" }); contracts.push({ ...token.contract, functionName: "totalSupply" });
const data = await multicall({ const data = await multicall({
contracts, contracts,
}); });
token.decimals = data[0].result; token.decimals = BigInt(data[0].result);
token.name = data[1].result; // token.name = data[1].result;
token.symbol = data[2].result; token.symbol = data[1].result;
token.totalSupply = data[3].result; token.totalSupply = data[2].result;
} }
} catch (error) { } catch (error) {
console.error("initV2", error); console.error("initV2", error);
@@ -142,9 +185,7 @@ export const useTokenStore = defineStore("token", {
walletStore.address, walletStore.address,
memeBurnerStore.config.contractAddress, memeBurnerStore.config.contractAddress,
]); ]);
const decimals = this.activeToken.decimals;
allowance = BigInt(allowance / BigInt(Math.pow(10, decimals)));
console.log("allowance", allowance); console.log("allowance", allowance);
return allowance; return allowance;
}, },
@@ -155,7 +196,7 @@ export const useTokenStore = defineStore("token", {
const memeBurnerStore = useMemeburnerStore(); const memeBurnerStore = useMemeburnerStore();
var approveHash = await this.activeToken.contract.write.approve([ var approveHash = await this.activeToken.contract.write.approve([
memeBurnerStore.config.contractAddress, memeBurnerStore.config.contractAddress,
amount * Math.pow(10, this.activeToken.decimals), amount,
]); ]);
console.log("approveHash", approveHash); console.log("approveHash", approveHash);
+15 -56
View File
@@ -1,22 +1,17 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { useWalletStoreV2 } from "@/stores/walletV2"; import { useWalletStoreV2 } from "@/stores/walletV2";
import QuoterJson from "@/assets/contracts/Quoter.json"; import QuoterJson from "@/assets/contracts/Quoter.json";
import UniswapPoolJson from "@/assets/contracts/UniswapPool.json"; import WethJson from "@/assets/contracts/WETH.json";
import BloodlineJson from "@/assets/contracts/Bloodline.json"; import BloodlineJson from "@/assets/contracts/Bloodline.json";
import { useMemeburnerStore } from "@/stores/memeburner";
import { getContract, multicall } from "@wagmi/core"; import { getContract, multicall } from "@wagmi/core";
export const useUniswapStore = defineStore("uniswap", { export const useUniswapStore = defineStore("uniswap", {
state: () => ({ state: () => ({
quoateV3Contract: {}, quoateV3Contract: {},
quoateV2Contract: {}, tokenIn: WethJson.contractAddress,
uniswapPoolContract: {}, tokenOut: BloodlineJson.contractAddress,
poolData: { fee: 10000n,
token0: null,
token1: null,
fee: null,
},
}), }),
getters: {}, getters: {},
actions: { actions: {
@@ -30,68 +25,32 @@ export const useUniswapStore = defineStore("uniswap", {
walletClient: walletStore.walletClient || walletStore.publicClient, walletClient: walletStore.walletClient || walletStore.publicClient,
}); });
this.uniswapPoolContract = getContract({
address: UniswapPoolJson.contractAddress,
abi: UniswapPoolJson.abi,
walletClient: walletStore.walletClient || walletStore.publicClient,
});
this.getPoolData();
}, },
async quoteExactInputSingle(amount, ethBase) { async quoteExactInputSingle(ethBase) {
try { try {
console.log("quoteExactInputSingle"); console.log("quoteExactInputSingle");
const memeBurnerStore = useMemeburnerStore();
// TODO: change it in your style
const tokenOut = BloodlineJson.contractAddress;
// tokenIn - WETH
const tokenIn = BigInt(this.poolData.token0) == BigInt(tokenOut) ? this.poolData.token1 : this.poolData.token0;
console.log("quoteExactInputSingle-parameter", { console.log("quoteExactInputSingle-parameter", {
tokenIn: tokenIn, // WETH tokenIn: this.tokenIn, // WETH
tokenOut: tokenOut, // BLOOD tokenOut: this.tokenOut, // BLOOD
fee: this.poolData.fee, fee: this.fee,
amountEthBase: ethBase, amountEthBase: ethBase,
pricelimit: 0, //sqrtPriceLimitX96 pricelimit: 0n, //sqrtPriceLimitX96
}); });
const quotedAmountOut = await this.quoateV3Contract.read.quoteExactInputSingle([ const quotedAmountOut = await this.quoateV3Contract.read.quoteExactInputSingle([
tokenIn, //weth this.tokenIn, //weth
tokenOut, //bloodline this.tokenOut, //bloodline
this.poolData.fee, this.fee,
ethBase, ethBase,
0, //sqrtPriceLimitX96 0n, //sqrtPriceLimitX96
]); ]);
console.log("quotedAmountOut", quotedAmountOut);
return {result: true, amount: quotedAmountOut}; return {result: true, amount: quotedAmountOut};
} catch (error) { } catch (error) {
return { result: false, amount: null }; return { result: false, amount: null };
} }
},
async getPoolData() {
console.log("getPoolData");
const contracts = [];
contracts.push(
{
...this.uniswapPoolContract,
functionName: "token0",
},
{
...this.uniswapPoolContract,
functionName: "token1",
},
{
...this.uniswapPoolContract,
functionName: "fee",
} }
); }
const data = await multicall({
contracts,
});
this.poolData.token0 = data[0].result;
this.poolData.token1 = data[1].result;
this.poolData.fee = data[2].result;
console.log("this.poolData", this.poolData);
},
},
}); });
+41 -13
View File
@@ -2,7 +2,7 @@ import { defineStore } from "pinia";
import { markRaw } from "vue"; import { markRaw } from "vue";
import { useTokenStore } from "./tokens"; import { useTokenStore } from "./tokens";
import { useRewardLockerStore } from "./rewardlocker"; import { useRewardLockerStore } from "./rewardlocker";
import { formatNumber } from "@/helper/helper.js";
import { import {
createConfig, createConfig,
configureChains, configureChains,
@@ -26,7 +26,6 @@ import { goerli, mainnet } from "@wagmi/core/chains";
import { publicProvider } from "@wagmi/core/providers/public"; import { publicProvider } from "@wagmi/core/providers/public";
import { alchemyProvider } from "@wagmi/core/providers/alchemy"; import { alchemyProvider } from "@wagmi/core/providers/alchemy";
export const useWalletStoreV2 = defineStore("walletV2", { export const useWalletStoreV2 = defineStore("walletV2", {
state: () => ({ state: () => ({
alchemy: null, alchemy: null,
@@ -41,16 +40,43 @@ export const useWalletStoreV2 = defineStore("walletV2", {
token: [], token: [],
}), }),
getters: { getters: {
sacrificeToken: (state) => state.token.filter((obj) => { sacrificeToken: (state) =>
state.token.filter((obj) => {
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
return obj.contractAddress !== tokenStore.memeToken.contractAddress; return obj.contractAddress !== tokenStore.memeToken.contractAddress;
}), }),
memeToken: (state) => state.token.find((obj) => { memeToken: (state) =>
state.token.find((obj) => {
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
return obj.contractAddress === tokenStore.memeToken.contractAddress; return obj.contractAddress === tokenStore.memeToken.contractAddress;
}), }),
unclaimedRewards() {
if (!this.memeToken?.unclaimedRewards) {
return 0n;
}
return this.memeToken.unclaimedRewards;
},
orderedUnstakedAmount() {
if (!this.memeToken?.orderedUnstakedAmount) {
return 0n;
}
return this.memeToken?.orderedUnstakedAmount;
},
staked() {
if (!this.memeToken?.staked) {
return 0n;
}
return this.memeToken?.staked;
},
balanceOf() {
if (!this.memeToken?.balanceOf) {
return 0n;
} else {
return this.memeToken?.balanceOf;
}
},
}, },
actions: { actions: {
async init() { async init() {
@@ -62,7 +88,6 @@ export const useWalletStoreV2 = defineStore("walletV2", {
this.address = account.address; this.address = account.address;
this.connected = true; this.connected = true;
} }
}, },
async connectWallet(connector) { async connectWallet(connector) {
try { try {
@@ -88,7 +113,7 @@ export const useWalletStoreV2 = defineStore("walletV2", {
}, },
async getTokenBalances() { async getTokenBalances() {
console.log("getTokenBalances"); console.log("getTokenBalances");
this.token = [] this.token = [];
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
var contracts = []; var contracts = [];
for (let index = 0; index < tokenStore.token.length; index++) { for (let index = 0; index < tokenStore.token.length; index++) {
@@ -101,16 +126,15 @@ export const useWalletStoreV2 = defineStore("walletV2", {
}); });
for (let index = 0; index < tokenStore.token.length; index++) { for (let index = 0; index < tokenStore.token.length; index++) {
const token = tokenStore.token[index]; const token = tokenStore.token[index];
const balanceOfDecimal = data[index].result / BigInt(Math.pow(10, token.decimals));
this.token.push({ this.token.push({
contractAddress: token.contractAddress, contractAddress: token.contractAddress,
balanceOf: Number(balanceOfDecimal), balanceOf: data[index].result,
}); });
} }
}, },
async loadWalletData() { async loadWalletData() {
if (!this.connected) { if (!this.connected) {
return return;
} }
console.log("loadWalletData"); console.log("loadWalletData");
const rewardlockerStore = useRewardLockerStore(); const rewardlockerStore = useRewardLockerStore();
@@ -118,13 +142,17 @@ export const useWalletStoreV2 = defineStore("walletV2", {
await this.getTokenBalances(); await this.getTokenBalances();
//MemeToken Staked //MemeToken Staked
const tokenStore = useTokenStore(); const tokenStore = useTokenStore();
const staked = await rewardlockerStore.getStaked(this.address); this.memeToken.staked = await rewardlockerStore.getStaked(this.address);
this.memeToken.staked = Number(staked) / Math.pow(10, tokenStore.memeToken.decimals);
const unclaimedRewardsArray = await rewardlockerStore.getTotalRewards(this.address); const unclaimedRewardsArray = await rewardlockerStore.getTotalRewards(this.address);
const unclaimedRewards = unclaimedRewardsArray[0] + unclaimedRewardsArray[1]; const unclaimedRewards = unclaimedRewardsArray[0] + unclaimedRewardsArray[1];
this.memeToken.unclaimedRewards = Number(unclaimedRewards) / Math.pow(10, tokenStore.memeToken.decimals) this.memeToken.unclaimedRewards = unclaimedRewards;
this.memeToken.orderedUnstakedCycles = await rewardlockerStore.unstakeOrdered();
} console.log("this.memeToken.orderedUnstakedCycles", this.memeToken.orderedUnstakedCycles);
this.memeToken.orderedUnstakedAmount = this.memeToken.orderedUnstakedCycles.reduce((x, y) => {
return x + y.result;
}, 0n);
},
}, },
// persist: true, // persist: true,
}); });
+41 -13
View File
@@ -2,8 +2,9 @@
<div class="cycle-page"> <div class="cycle-page">
<div class="cycle-header container container--variant1"> <div class="cycle-header container container--variant1">
<div class="bloodline-page-headline header" ref="observerElement">Bloodline Cycle</div> <div class="bloodline-page-headline header" ref="observerElement">Bloodline Cycle</div>
<div class="bloodline-page-description low-mid-text"> <div class="bloodline-page-description mid-mid-text">
Claim and trade your $BDL at each cycle's end. Become the most powerful bloodline and win extra rewards. Claim and trade your $BLOOD at each cycle's end. Become the most powerful bloodline and win extra
rewards.
</div> </div>
</div> </div>
<div class="slider-wrapper" :class="{ sticking: sticking }" ref="target"> <div class="slider-wrapper" :class="{ sticking: sticking }" ref="target">
@@ -27,7 +28,9 @@
> >
<template v-if="difference > 0"> <template v-if="difference > 0">
<div class="round-finish-info-key">Sacrifice Goal:</div> <div class="round-finish-info-key">Sacrifice Goal:</div>
<div class="round-finish-info-value">{{ cycleStore.getCurrentCycleData?.goalInBLD }} $BDL</div> <div class="round-finish-info-value">
{{ cycleStore.getCurrentCycleData?.goalInBLD / 10n ** tokenStore.memeToken.decimals }} $BLOOD
</div>
<div class="round-finish-info-key">Time left:</div> <div class="round-finish-info-key">Time left:</div>
<div class="round-finish-info-value">{{ days }} {{ hours }} {{ minutes }}</div> <div class="round-finish-info-value">{{ days }} {{ hours }} {{ minutes }}</div>
</template> </template>
@@ -38,12 +41,15 @@
<template v-if="cycleStore.currentCycle !== cycleStore.activeCycle"> <template v-if="cycleStore.currentCycle !== cycleStore.activeCycle">
<div class="bloodline-border bloodline-border purple cycle-winner" v-if="cycleStore.getCycleWinner"> <div class="bloodline-border bloodline-border purple cycle-winner" v-if="cycleStore.getCycleWinner">
<div class="cycle-winner-left"> <div class="cycle-winner-left">
<div class="cycle-winner-headline">Clan Winner</div> <div class="cycle-winner-headline">Cycle Winner</div>
<div class="cycle-winner-subheadline">+25% Clan Bonus</div> <div class="cycle-winner-subheadline">
+ Clan Bonus on {{ cycleStore.getCycleWinner.name }} Sacrifice
</div>
</div> </div>
<div class="cycle-winner-right"> <div class="cycle-winner-right">
<div class="cycle-winner-logo"> <div class="cycle-winner-logo">
<img :src="cycleStore.getCycleWinner.vampwinner" alt="" /> <img class="logo" :src="cycleStore.getCycleWinner.vamplogo" alt="" />
<img class="crown" src="/assets/img/winnerCrown.png" alt="" />
</div> </div>
<div class="cycle-winner-name">{{ cycleStore.getCycleWinner.name }}</div> <div class="cycle-winner-name">{{ cycleStore.getCycleWinner.name }}</div>
</div> </div>
@@ -77,7 +83,12 @@
<div class="bloodline-container"> <div class="bloodline-container">
<div class="bloodline-border purple">Get up to +25% Clan Bonus on your sacrifice.</div> <div class="bloodline-border purple">Get up to +25% Clan Bonus on your sacrifice.</div>
</div> </div>
<template v-if="!cycleStore.cycles[cycleStore.activeCycle]">
<Vue3Lottie :animationData="ChartLoading" :height="400" :width="400" />
</template>
<template v-else>
<blood-chart :data="cycleStore.cycles[cycleStore.activeCycle]"></blood-chart> <blood-chart :data="cycleStore.cycles[cycleStore.activeCycle]"></blood-chart>
</template>
</div> </div>
</div> </div>
</div> </div>
@@ -88,13 +99,19 @@ import { inject, ref, onMounted, onBeforeUnmount } from "vue";
import BloodChart from "@/components/BloodChart.vue"; import BloodChart from "@/components/BloodChart.vue";
import TokenClaim from "@/components/TokenClaim.vue"; import TokenClaim from "@/components/TokenClaim.vue";
import { useTokenStore } from "@/stores/tokens";
import { useMemeburnerStore } from "@/stores/memeburner"; import { useMemeburnerStore } from "@/stores/memeburner";
import LoadingComponent from "@/components/LoadingComponent.vue"; import LoadingComponent from "@/components/LoadingComponent.vue";
import { useCycleStore } from "@/stores/cycles"; import { useCycleStore } from "@/stores/cycles";
import { useRewardLockerStore } from "@/stores/rewardlocker"; import { useRewardLockerStore } from "@/stores/rewardlocker";
import { Vue3Lottie } from "vue3-lottie";
import ChartLoading from "@/assets/lottie/ChartLoading.json";
const cycleStore = useCycleStore(); const cycleStore = useCycleStore();
const tokenStore = useTokenStore();
const days = ref(null); const days = ref(null);
const hours = ref(null); const hours = ref(null);
@@ -256,24 +273,35 @@ function timeBetweenDates(expirationTimestamp) {
.cycle-winner-headline .cycle-winner-headline
font-size: 24px font-size: 24px
.cycle-winner-subheadline .cycle-winner-subheadline
font-size: 12px font-size: 14px
.cycle-winner-right .cycle-winner-right
display: flex display: flex
flex-direction: column flex-direction: column
justify-content: space-between justify-content: space-between
align-items: center align-items: center
.cycle-winner-logo .cycle-winner-logo
height: 48px
width: 48px
position: relative
img
height: 72px height: 72px
width: 72px width: 72px
position: relative
img
&.logo
height: 100%
width: 100%
border: 1px solid yellow
border-radius: 50% border-radius: 50%
img
&.crown
position: absolute position: absolute
left: 50% top: -10px
top: 10px
transform: translate(-50%, -50%) transform: translate(-50%, -50%)
left: 50%
// height: 72px
// width: 72px
// border-radius: 50%
// position: absolute
// left: 50%
// top: 10px
// transform: translate(-50%, -50%)
&.inactive &.inactive
img img
height: 100% height: 100%
+3 -2
View File
@@ -66,6 +66,7 @@ function openTutorialFunc(e) {
text-align: center text-align: center
margin-top: 24px margin-top: 24px
margin-bottom: 48px margin-bottom: 48px
padding: 0 12px
@media (min-width: 992px) @media (min-width: 992px)
font-size: 48px font-size: 48px
margin-top: 0px margin-top: 0px
@@ -73,6 +74,7 @@ function openTutorialFunc(e) {
text-shadow: unset text-shadow: unset
line-height: 80px line-height: 80px
font-weight: 600 font-weight: 600
padding: 0
.chart-wrapper-coin .chart-wrapper-coin
display: flex display: flex
@@ -106,7 +108,6 @@ function openTutorialFunc(e) {
margin-right: auto margin-right: auto
pointer-events: none pointer-events: none
user-select: none user-select: none
@media (min-width: 992px)
width: 100% width: 100%
.chart-wrapper .chart-wrapper
width: 600px width: 600px
@@ -129,7 +130,7 @@ function openTutorialFunc(e) {
#section-header-container #section-header-container
margin: 72px 0 margin: 48px 0
scroll-margin: 150px scroll-margin: 150px
.tutorial-header .tutorial-header
display: flex display: flex
+2 -1
View File
@@ -1,4 +1,5 @@
import { fileURLToPath, URL } from 'node:url' import { fileURLToPath, URL } from 'node:url'
import svgLoader from "vite-svg-loader";
import { defineConfig } from 'vite' import { defineConfig } from 'vite'
import GlobalsPolyfills from "@esbuild-plugins/node-globals-polyfill"; import GlobalsPolyfills from "@esbuild-plugins/node-globals-polyfill";
@@ -9,7 +10,7 @@ import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
base: "./", base: "./",
plugins: [vue()], plugins: [vue(), svgLoader()],
optimizeDeps: { optimizeDeps: {
esbuildOptions: { esbuildOptions: {
plugins: [ plugins: [
+2332 -2200
View File
File diff suppressed because it is too large Load Diff