mint
7
.env.development
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
VITE_BASE_API='https://oauth-svr.cebggame.com/mint'
|
||||||
|
VUE_APP_GPAL_API='http://192.168.100.83:4000/sns'
|
||||||
|
VITE_TOKENID_ID = '0x34a1'
|
||||||
|
VITE_ERC_ADDRESS = '0xFd42bfb03212dA7e1A4608a44d7658641D99CF34'
|
||||||
|
VITE_CFNFT_ADDRESS = '0xaa34B79A0Ab433eaC900fB3CB9f191F5Cd27501D'
|
||||||
|
VITE_CLAIM_ADDRESS = '0xf45702180314187a3549FEDac3B78349b47ca6A0'
|
||||||
|
VITE_CLAIMWL_ADDRESS = '0x31f29c9a3d0c1c13c825475aebf0d964b5b47c45'
|
7
.env.production
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
VITE_BASE_API='https://oauth-svr.cebggame.com/mint'
|
||||||
|
VUE_APP_GPAL_API='http://192.168.100.83:4000/sns'
|
||||||
|
VITE_TOKENID_ID = '0x34a1'
|
||||||
|
VITE_ERC_ADDRESS = '0xFd42bfb03212dA7e1A4608a44d7658641D99CF34'
|
||||||
|
VITE_CFNFT_ADDRESS = '0xaa34B79A0Ab433eaC900fB3CB9f191F5Cd27501D'
|
||||||
|
VITE_CLAIM_ADDRESS = '0xf45702180314187a3549FEDac3B78349b47ca6A0'
|
||||||
|
VITE_CLAIMWL_ADDRESS = '0x31f29c9a3d0c1c13c825475aebf0d964b5b47c45'
|
24
.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
3
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"recommendations": ["Vue.volar"]
|
||||||
|
}
|
7
README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Vue 3 + Vite
|
||||||
|
|
||||||
|
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
|
||||||
|
|
||||||
|
## Recommended IDE Setup
|
||||||
|
|
||||||
|
- [VS Code](https://code.visualstudio.com/) + [Vue - Official](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously Volar) and disable Vetur
|
13
index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Vite + Vue</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
17360
package-lock.json
generated
Normal file
32
package.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "mint",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --host --mode dev",
|
||||||
|
"build": "vite build --mode dev",
|
||||||
|
"build:test": "vite build --mode test",
|
||||||
|
"build:prod": "vite build --mode production",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.7.2",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
|
"element-plus": "^2.7.3",
|
||||||
|
"ethers": "5.4",
|
||||||
|
"postcss-px-to-viewport": "^1.1.1",
|
||||||
|
"sass": "^1.77.2",
|
||||||
|
"vue": "^3.4.21",
|
||||||
|
"rollup-plugin-polyfill-node": "^0.12.0",
|
||||||
|
"web3": "^4.9.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@imtbl/sdk": "^1.36.4",
|
||||||
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^5.4.5",
|
||||||
|
"vite": "^5.2.0",
|
||||||
|
"vite-plugin-node-polyfills": "^0.22.0"
|
||||||
|
}
|
||||||
|
}
|
24
postcss.config.cjs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
'postcss-px-to-viewport': {
|
||||||
|
unitToConvert: 'px', // 需要转换的单位,默认为"px"
|
||||||
|
viewportWidth: 1920, // 设计稿的视口宽度
|
||||||
|
unitPrecision: 5, // 单位转换后保留的精度
|
||||||
|
propList: ['*'], // 能转化为vw的属性列表
|
||||||
|
viewportUnit: 'vw', // 希望使用的视口单位
|
||||||
|
fontViewportUnit: 'vw', // 字体使用的视口单位
|
||||||
|
selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
|
||||||
|
minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
|
||||||
|
mediaQuery: false, // 媒体查询里的单位是否需要转换单位
|
||||||
|
replace: true, // 是否直接更换属性值,而不添加备用属性
|
||||||
|
exclude: undefined, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
|
||||||
|
include: undefined, // 如果设置了include,那将只有匹配到的文件才会被转换
|
||||||
|
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
|
||||||
|
landscapeUnit: 'vw', // 横屏时使用的单位
|
||||||
|
landscapeWidth: 1920 // 横屏时使用的视口宽度
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
1
public/vite.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
116
src/App.vue
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<script setup>
|
||||||
|
import HelloWorld from './view/mintIndex.vue'
|
||||||
|
import FooterView from './components/footerView.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<!-- <div>
|
||||||
|
<div @click="immuTableLogin">immuTableLogin</div>
|
||||||
|
<a href="https://vitejs.dev" target="_blank">
|
||||||
|
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
||||||
|
</a>
|
||||||
|
<a href="https://vuejs.org/" target="_blank">
|
||||||
|
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
|
||||||
|
</a>
|
||||||
|
</div> -->
|
||||||
|
<HelloWorld />
|
||||||
|
<FooterView />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
div,
|
||||||
|
span,
|
||||||
|
object,
|
||||||
|
iframe,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
blockquote,
|
||||||
|
pre,
|
||||||
|
abbr,
|
||||||
|
address,
|
||||||
|
cite,
|
||||||
|
code,
|
||||||
|
del,
|
||||||
|
dfn,
|
||||||
|
em,
|
||||||
|
img,
|
||||||
|
ins,
|
||||||
|
kbd,
|
||||||
|
q,
|
||||||
|
samp,
|
||||||
|
small,
|
||||||
|
strong,
|
||||||
|
sub,
|
||||||
|
sup,
|
||||||
|
var,
|
||||||
|
b,
|
||||||
|
i,
|
||||||
|
dl,
|
||||||
|
dt,
|
||||||
|
dd,
|
||||||
|
ol,
|
||||||
|
ul,
|
||||||
|
li,
|
||||||
|
fieldset,
|
||||||
|
form,
|
||||||
|
label,
|
||||||
|
legend,
|
||||||
|
table,
|
||||||
|
caption,
|
||||||
|
tbody,
|
||||||
|
tfoot,
|
||||||
|
thead,
|
||||||
|
tr,
|
||||||
|
th,
|
||||||
|
td,
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
canvas,
|
||||||
|
details,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
section,
|
||||||
|
summary,
|
||||||
|
time,
|
||||||
|
mark,
|
||||||
|
audio,
|
||||||
|
video {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
outline: 0;
|
||||||
|
|
||||||
|
font-size: 100%;
|
||||||
|
|
||||||
|
vertical-align: baseline;
|
||||||
|
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
list-style: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
1339
src/abi/CFNFTGame.json
Normal file
836
src/abi/ImmutableERC20MinterBurnerPermit.json
Normal file
492
src/abi/NFTClaimStage2.json
Normal file
594
src/abi/NFTClaimStage2WL.json
Normal file
63
src/abi/mint.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
const MINT_CONTRACT_ADDRESS='0x31f29c9a3d0c1c13c825475aebf0d964b5b47c45'
|
||||||
|
const RPC='https://rpc.testnet.immutable.com/'
|
||||||
|
|
||||||
|
const requestChain = async (rpc, method, params) => {
|
||||||
|
const data = {
|
||||||
|
id: Date.now(),
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
}
|
||||||
|
const options: any = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
}
|
||||||
|
return fetch(rpc, options, DEFAULT_TIMEOUT).then(res => res.json())
|
||||||
|
}
|
||||||
|
|
||||||
|
const queryMintData = async(user, data) => {
|
||||||
|
const params = [{
|
||||||
|
from: user,
|
||||||
|
to: MINT_CONTRACT_ADDRESS,
|
||||||
|
data,
|
||||||
|
}, 'latest']
|
||||||
|
return requestChain(RPC, 'eth_call', params)
|
||||||
|
}
|
||||||
|
// 当前用户白单数量
|
||||||
|
|
||||||
|
const fetchWLCount = async(user) => {
|
||||||
|
const data = '0xe65ee803'
|
||||||
|
return queryMintData(user, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mintConfig
|
||||||
|
* {
|
||||||
|
* maxSupply: 2000, // 当前活动可mint总数
|
||||||
|
* currency: 0x21321, // 需要支付的代币地址
|
||||||
|
* mintPrice: 100000000000000, // 需要支付的代币数量, 单位: wei
|
||||||
|
* feeToAddress: 0x1231231 // 接收代币的钱包地址, 前端不需要管
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
const fetchMintConfig = async() => {
|
||||||
|
const data = '0xe7cc7244'
|
||||||
|
return queryMintData(MINT_CONTRACT_ADDRESS, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 所有用户已mint的nft总数
|
||||||
|
const fetchMintedCount = async()=> {
|
||||||
|
const data = '0x34eafb11'
|
||||||
|
return queryMintData(MINT_CONTRACT_ADDRESS, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 已mint的NFT列表
|
||||||
|
const fetchUserNftList = async(user) => {
|
||||||
|
const data = '0x7d10ab3f'
|
||||||
|
return queryMintData(user, data)
|
||||||
|
}
|
||||||
|
|
BIN
src/assets/home/Arrow2.png
Normal file
After Width: | Height: | Size: 376 B |
BIN
src/assets/home/Arrow3.png
Normal file
After Width: | Height: | Size: 443 B |
BIN
src/assets/home/Close counter.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
src/assets/home/Connect Menu1.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
src/assets/home/Connect Menu2.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
BIN
src/assets/home/Counter Fire Logo.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
src/assets/home/Discord.png
Normal file
After Width: | Height: | Size: 900 B |
BIN
src/assets/home/ETHicon.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/home/Empty state.png
Normal file
After Width: | Height: | Size: 81 KiB |
BIN
src/assets/home/Gen2_raw.gif
Normal file
After Width: | Height: | Size: 6.0 MiB |
BIN
src/assets/home/Golden_GIF.gif
Normal file
After Width: | Height: | Size: 6.6 MiB |
BIN
src/assets/home/Icon_!.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/home/KeyVisual.png
Normal file
After Width: | Height: | Size: 1.9 MiB |
BIN
src/assets/home/Links web icon.png
Normal file
After Width: | Height: | Size: 442 B |
BIN
src/assets/home/Mint Button_Ash.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
src/assets/home/Mint Button_Shape1.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/home/Mint Button_Shape2.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/assets/home/Nav bar_character.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
src/assets/home/Normal_GIF_1.gif
Normal file
After Width: | Height: | Size: 6.3 MiB |
BIN
src/assets/home/Opening.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/home/Picture01.png
Normal file
After Width: | Height: | Size: 394 KiB |
BIN
src/assets/home/Purple_GIF.gif
Normal file
After Width: | Height: | Size: 6.3 MiB |
BIN
src/assets/home/X.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/home/andriod.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
src/assets/home/app.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
src/assets/home/appstore.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/home/arrow1.png
Normal file
After Width: | Height: | Size: 333 B |
BIN
src/assets/home/blind box img02.png
Normal file
After Width: | Height: | Size: 131 KiB |
BIN
src/assets/home/blind boxbg02.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
src/assets/home/blur.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/assets/home/close_btn.png
Normal file
After Width: | Height: | Size: 731 B |
BIN
src/assets/home/com_Discord_icon.png
Normal file
After Width: | Height: | Size: 1005 B |
BIN
src/assets/home/com_X_icon.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/home/com_Youtube_icon.png
Normal file
After Width: | Height: | Size: 695 B |
BIN
src/assets/home/counterfire-apk.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/home/google.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
src/assets/home/googleplay.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/home/icon_ConnectWallet.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/home/icon_OKXwallet.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/assets/home/icon_metaMask.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/home/loding .png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/home/mint bg.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
src/assets/home/mint_Logo1.png
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/home/mint_Logo2.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/home/nav bg.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/home/nav.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
src/assets/home/okx.png
Normal file
After Width: | Height: | Size: 1002 B |
BIN
src/assets/home/open sea.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/home/per-season.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
src/assets/home/playBtn.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/text/Anton-Regular.ttf
Normal file
BIN
src/assets/text/Poppins-Regular.ttf
Normal file
BIN
src/assets/text/Poppins-SemiBold.ttf
Normal file
18
src/assets/text/text.css
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Anton';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url('./Anton-Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url('./Poppins-Regular.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Poppins-SemiBold';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: url('./Poppins-SemiBold.ttf') format('truetype');
|
||||||
|
}
|
1
src/assets/vue.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
|
After Width: | Height: | Size: 496 B |
52
src/components/HelloWorld.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <div @click="immuTableLogin">immuTableLogin</div> -->
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<button type="button" @click="count++">count is {{ count }}</button>
|
||||||
|
<p>
|
||||||
|
Edit
|
||||||
|
<code>components/HelloWorld.vue</code> to test HMR
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Check out
|
||||||
|
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
|
||||||
|
>create-vue</a
|
||||||
|
>, the official Vue + Vite starter
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Install
|
||||||
|
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
|
||||||
|
in your IDE for a better DX
|
||||||
|
</p>
|
||||||
|
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { getConnect } from "./../wallet/index.js"
|
||||||
|
|
||||||
|
// defineProps({
|
||||||
|
// msg: String,
|
||||||
|
// })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const count = ref(0)
|
||||||
|
// const immuTableLogin = async () => {
|
||||||
|
// console.log('----')
|
||||||
|
// try{
|
||||||
|
// const walletLogin = await getConnect()
|
||||||
|
// console.log(walletLogin)
|
||||||
|
// } catch (e) {
|
||||||
|
// console.log(e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.read-the-docs {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
</style>../wallet/index1.js
|
57
src/components/footerView.vue
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<template>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="footer-left">COPYRIGHT © Candy Bubble Global Limited.ALL RIGHTS RESERVED.</div>
|
||||||
|
<div class="footer-right">
|
||||||
|
<li>
|
||||||
|
<a href="https://discord.com/invite/counterfire" target="_blank">
|
||||||
|
<img src="./../assets/home/com_Discord_icon.png" alt="">
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://twitter.com/@playCounterFire" target="_blank">
|
||||||
|
<img src="./../assets/home/com_X_icon.png" alt="">
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://youtube.com/@_CounterFire" target="_blank">
|
||||||
|
<img src="./../assets/home/com_Youtube_icon.png" alt="">
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.footer {
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 45px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-top: 2px solid #1A1821;
|
||||||
|
background: #0f1013;
|
||||||
|
.footer-left {
|
||||||
|
color: #877E98;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.footer-right {
|
||||||
|
display: flex;
|
||||||
|
li {
|
||||||
|
width: 31px;
|
||||||
|
height: 24px;
|
||||||
|
margin-left: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
86
src/components/loading.vue
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog :model-value="Loading" :show-close="false" :modal="false" :close-on-click-modal="false" class="RecentlyLoading">
|
||||||
|
<div class="recentlyTit">
|
||||||
|
<div>
|
||||||
|
<img src="./../assets/home/loding .png" alt />
|
||||||
|
</div>
|
||||||
|
<p>Please wait. Data is loading</p>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ElDialog } from "element-plus";
|
||||||
|
export default {
|
||||||
|
name: "Loading",
|
||||||
|
props: {
|
||||||
|
Loading: Boolean
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// Loading:
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-overlay-dialog{
|
||||||
|
// .RecentlyLoading {
|
||||||
|
// ::v-deep
|
||||||
|
.RecentlyLoading .el-dialog {
|
||||||
|
width: 480px;
|
||||||
|
// height: 60px;
|
||||||
|
background: url("@/assets/common/bg button.png") no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin-top: 85vh !important;
|
||||||
|
.el-dialog__header {
|
||||||
|
padding: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
.el-dialog__body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.recentlyTit {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 50px;
|
||||||
|
div {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
animation: turn 3s linear infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes turn {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
-webkit-transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
-webkit-transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
116
src/components/starTimer copy.vue
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="count-down">
|
||||||
|
{{ day }}
|
||||||
|
<span>D : </span>
|
||||||
|
{{ hour }}
|
||||||
|
<span>H : </span>
|
||||||
|
{{ min }}
|
||||||
|
<span>M : </span>
|
||||||
|
{{ sec }}
|
||||||
|
<span>S</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
//要求必须传入两个时间 开始时间和结束时间
|
||||||
|
//当前也可以只传入一个时间,逻辑就不涉及开始倒计时和结束倒计时,可以减少一个判断
|
||||||
|
startTime: {
|
||||||
|
type: Number,
|
||||||
|
require: true
|
||||||
|
},
|
||||||
|
endTime: {
|
||||||
|
type: Number,
|
||||||
|
require: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setup(props) {
|
||||||
|
//倒计时剩几天
|
||||||
|
const day = ref('--')
|
||||||
|
//倒计时剩几小时
|
||||||
|
const hour = ref('--')
|
||||||
|
//倒计时剩几分钟
|
||||||
|
const min = ref('--')
|
||||||
|
//倒计时剩几秒
|
||||||
|
const sec = ref('--')
|
||||||
|
//判断是否开始倒计时
|
||||||
|
const start = ref(false)
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
//页面一进来开始查询是否开始倒计时
|
||||||
|
getTimes();
|
||||||
|
});
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
//页面销毁的时候清除定时器
|
||||||
|
window.clearInterval(timer);
|
||||||
|
});
|
||||||
|
const getTimes = () => {
|
||||||
|
const date = new Date().getTime();
|
||||||
|
//判断1.如果当前时间小于开始时间 那么意味着活动还没开始 此时的倒计时就是距离活动开始的倒计时
|
||||||
|
if (Number(date) < Number(props.startTime)) {
|
||||||
|
//传入定时器的时间也是开始时间
|
||||||
|
countDown(props.startTime);
|
||||||
|
}
|
||||||
|
//判断2.当前时间大于开始时间且小于结束时间
|
||||||
|
//那么意味着活动正在进行 此时的倒计时就是距离活动结束的倒计时
|
||||||
|
if (
|
||||||
|
Number(date) >= Number(props.startTime) &&
|
||||||
|
Number(date) < Number(props.endTime)
|
||||||
|
) {
|
||||||
|
//传入定时器的时间就是结束时间
|
||||||
|
countDown(props.endTime);
|
||||||
|
}
|
||||||
|
//判断3.当前时间大于结束时间 意味着活动已经结束 倒计时也就结束了
|
||||||
|
if (Number(date) > Number(props.endTime)) {
|
||||||
|
start.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const countDown = time => {
|
||||||
|
//说明活动未开始或者活动正在进行中 开始倒计时
|
||||||
|
start.value = true;
|
||||||
|
let nowTime = new Date().getTime();
|
||||||
|
let inputTime = time;
|
||||||
|
let timer = null;
|
||||||
|
//如果传进来的时间-当前时间 == 0 说明倒计时结束
|
||||||
|
let times = (inputTime - nowTime) / 1000;
|
||||||
|
timer = setInterval(() => {
|
||||||
|
if (times == 0) {
|
||||||
|
//倒计时结束时 不确定是哪个倒计时 所以在执行一遍getTimes()
|
||||||
|
//如果第一次传进来的时间是开始倒计时 那么再次执行getTimes()就会继续传入结束时间,开始结束倒计时
|
||||||
|
//如果第一次传进来的是结束倒计时 那么再次执行getTimes() 就会执行判断3 结束倒计时
|
||||||
|
getTimes();
|
||||||
|
clearInterval(timer);
|
||||||
|
window.clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//定时器开始 times倒计时每一秒都要减1
|
||||||
|
times--;
|
||||||
|
//js获取剩余天数
|
||||||
|
let d = parseInt(String(times / 60 / 60 / 24));
|
||||||
|
d = d < 10 ? "0" + d : d;
|
||||||
|
//js获取剩余小时
|
||||||
|
let h = parseInt(String((times / 60 / 60) % 24));
|
||||||
|
h = h < 10 ? "0" + h : h;
|
||||||
|
//js获取剩余分钟
|
||||||
|
let m = parseInt(String((times / 60) % 60));
|
||||||
|
m = m < 10 ? "0" + m : m;
|
||||||
|
//js获取剩余秒
|
||||||
|
let s = parseInt(String(times % 60));
|
||||||
|
s = s < 10 ? "0" + s : s;
|
||||||
|
//赋值给当前变量
|
||||||
|
day.value = d;
|
||||||
|
hour.value = h;
|
||||||
|
min.value = m;
|
||||||
|
sec.value = s;
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
return { day, hour, min, sec, start };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
72
src/components/starTimer.vue
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
{{hour}}h:{{min}}m:{{sec}}s
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted } from 'vue';
|
||||||
|
const props = defineProps({
|
||||||
|
getAddress: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let remainingTime = ref(0); // 24小时 = 86400秒
|
||||||
|
const day = ref(0);
|
||||||
|
const hour = ref(0);
|
||||||
|
const min = ref(0);
|
||||||
|
const sec = ref(0);
|
||||||
|
let intervalId = null
|
||||||
|
const starTimer = () => {
|
||||||
|
let nowTime = new Date().getTime();
|
||||||
|
// let str = localStorage.getItem(`openTime${props.getAddress}`)
|
||||||
|
let strTime = (nowTime+86400000 - nowTime) / 1000
|
||||||
|
|
||||||
|
intervalId = setInterval(() => {
|
||||||
|
if (strTime >= 1) {
|
||||||
|
// remainingTime.value -= 1;
|
||||||
|
strTime--;
|
||||||
|
//js获取剩余天数
|
||||||
|
let d = Math.floor(strTime / 60 / 60 / 24);
|
||||||
|
d = d < 10 ? "0" + d : d;
|
||||||
|
//js获取剩余小时
|
||||||
|
let h = Math.floor((strTime / 60 / 60) % 24);
|
||||||
|
h = h < 10 ? "0" + h : h;
|
||||||
|
//js获取剩余分钟
|
||||||
|
let m = Math.floor((strTime / 60) % 60);
|
||||||
|
m = m < 10 ? "0" + m : m;
|
||||||
|
//js获取剩余秒
|
||||||
|
let s = Math.floor(strTime % 60);
|
||||||
|
s = s < 10 ? "0" + s : s;
|
||||||
|
//赋值给当前变量
|
||||||
|
day.value = d;
|
||||||
|
hour.value = h;
|
||||||
|
min.value = m;
|
||||||
|
sec.value = s;
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem(`openTime${props.getAddress}`)
|
||||||
|
clearInterval(intervalId);
|
||||||
|
intervalId = null
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
// 判断是否登录 判断是否显示mint成功倒计时
|
||||||
|
const isOpenTime = () => {
|
||||||
|
let openTime = localStorage.getItem(`openTime${props.getAddress}`)
|
||||||
|
// if(props.getAddress) {
|
||||||
|
// if(props.getAddress == openTime.split('-')[0]) {
|
||||||
|
starTimer()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
isOpenTime()
|
||||||
|
// 清除定时器
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
14
src/main.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import './style.css'
|
||||||
|
import './assets/text/text.css'
|
||||||
|
import App from './App.vue'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
import passportInit from './wallet/initPassport.js'
|
||||||
|
|
||||||
|
const app = createApp(App)
|
||||||
|
|
||||||
|
|
||||||
|
app.use(ElementPlus)
|
||||||
|
app.use(passportInit)
|
||||||
|
app.mount('#app')
|
90
src/style.css
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/* :root {
|
||||||
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color-scheme: light dark;
|
||||||
|
color: rgba(255, 255, 255, 0.87);
|
||||||
|
background-color: #242424;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.25s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
border-color: #646cff;
|
||||||
|
}
|
||||||
|
button:focus,
|
||||||
|
button:focus-visible {
|
||||||
|
outline: 4px auto -webkit-focus-ring-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
color: #213547;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #747bff;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
body {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
130
src/utils/webapi.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
// const API_BASE = import.meta.env.VUE_APP_BASE_API;
|
||||||
|
// console.log(API_BASE)
|
||||||
|
// import axios from 'axios'
|
||||||
|
|
||||||
|
// const toJson = res => res.json();
|
||||||
|
|
||||||
|
|
||||||
|
// const httpPost = async (url, data) => {
|
||||||
|
// const token = store.state.user.token;
|
||||||
|
// let headers = {"Content-Type": "application/json"};
|
||||||
|
// // let token = token;
|
||||||
|
// if (token) {
|
||||||
|
// headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
// }
|
||||||
|
// return fetch(url, {
|
||||||
|
// method: "POST",
|
||||||
|
// body: JSON.stringify(data),
|
||||||
|
// headers
|
||||||
|
// }).then(toJson);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const httpGet = async (url) => {
|
||||||
|
// const token = ''
|
||||||
|
// let headers = {"Content-Type": "application/json"};
|
||||||
|
// if (token) {
|
||||||
|
// headers['Authorization'] = `Bearer ${token}`;
|
||||||
|
// }
|
||||||
|
// return fetch(url, {
|
||||||
|
// method: "GET",
|
||||||
|
// headers
|
||||||
|
// }).then(toJson);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const base58Alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
||||||
|
|
||||||
|
// export const hexToBase58 = (hexString) => {
|
||||||
|
// hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16));
|
||||||
|
// let base58String = '';
|
||||||
|
// // eslint-disable-next-line no-undef
|
||||||
|
// let num = BigInt('0x' + hexString);
|
||||||
|
// while (num > 0n) {
|
||||||
|
// const remainder = num % 58n;
|
||||||
|
// num = num / 58n;
|
||||||
|
// base58String = base58Alphabet[Number(remainder)] + base58String;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return base58String;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const aesEncrypt = (plaintText, key) => {
|
||||||
|
// key = CryptoJS.SHA1(key).toString().substring(0,16)
|
||||||
|
// key = CryptoJS.enc.Base64.parse(key)
|
||||||
|
// let encryptedData = CryptoJS.AES.encrypt(plaintText, key, {
|
||||||
|
// mode: CryptoJS.mode.ECB,
|
||||||
|
// padding: CryptoJS.pad.Pkcs7
|
||||||
|
// });
|
||||||
|
|
||||||
|
// return encryptedData.toString(CryptoJS.format.Hex);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const loginNonce = async (address) => {
|
||||||
|
// const nonceRes = await fetch(`${API_BASE}/api/wallet/nonce?address=${address}`).then(toJson);
|
||||||
|
// const { nonce } = nonceRes.data;
|
||||||
|
// return nonce;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const loginWithSignature = async (message, signature, activity, wallet) => {
|
||||||
|
// let fps = await fp.load();
|
||||||
|
// let result = await fps.get()
|
||||||
|
// const clientId = result.clientId;
|
||||||
|
// return fetch(`${API_BASE}/api/wallet/login`, {
|
||||||
|
// method: "POST",
|
||||||
|
// body: JSON.stringify({ message, signature, activity,clientId, wallet }),
|
||||||
|
// headers: {
|
||||||
|
// "Content-Type": "application/json",
|
||||||
|
// },
|
||||||
|
// }).then(toJson);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export const beginPost = async (activity) => {
|
||||||
|
// return fetch(`${API_BASE}/api/tasks/begin_task`, {
|
||||||
|
// method: "POST",
|
||||||
|
// body: JSON.stringify({ activity }),
|
||||||
|
// headers: {
|
||||||
|
// "Content-Type": "application/json",
|
||||||
|
// },
|
||||||
|
// }).then(toJson);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * past 方法
|
||||||
|
// * @param {string} url [请求地址]
|
||||||
|
// * @param {object} params [请求参数]
|
||||||
|
// */
|
||||||
|
// function post(url, params) {
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// axios
|
||||||
|
// .post(url, QS.stringify(params))
|
||||||
|
// .then((res) => {
|
||||||
|
// resolve(res.data);
|
||||||
|
// })
|
||||||
|
// .catch((err) => {
|
||||||
|
// reject(err.data);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 查询是否在白名单
|
||||||
|
// export const apiCheck = async (address) => {
|
||||||
|
// const url = `${API_BASE}/`;
|
||||||
|
// return httpGet(url, {address})
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 获取claim方法的参数
|
||||||
|
// export const apiSendCode = async (email) => {
|
||||||
|
// const url = `${API_BASE}/api/email/send_code`;
|
||||||
|
// return httpPost(url, {email})
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// // 活动时间结束
|
||||||
|
// export const endActivity = async (time) => {
|
||||||
|
// var now = new Date().getTime();
|
||||||
|
// if(time <= now) {
|
||||||
|
// return false
|
||||||
|
// } else {
|
||||||
|
// return true
|
||||||
|
// }
|
||||||
|
// }
|
2455
src/view/mintIndex copy.vue
Normal file
2455
src/view/mintIndex.vue
Normal file
441
src/wallet/index.js
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
import Web3 from 'web3'
|
||||||
|
import { config, passport } from '@imtbl/sdk';
|
||||||
|
import { ethers, providers } from 'ethers';
|
||||||
|
|
||||||
|
import ERC_abi from './../abi/ImmutableERC20MinterBurnerPermit.json'
|
||||||
|
import CFNFT_abi from './../abi/CFNFTGame.json'
|
||||||
|
import CLAIM_abi from './../abi/NFTClaimStage2.json'
|
||||||
|
import CLAIMWL_abi from './../abi/NFTClaimStage2WL.json'
|
||||||
|
var abis = {
|
||||||
|
"ERC": ERC_abi,
|
||||||
|
"CFNFT": CFNFT_abi,
|
||||||
|
"CLAIM": CLAIM_abi,
|
||||||
|
"CLAIMWL": CLAIMWL_abi,
|
||||||
|
}
|
||||||
|
var ERCAddress = import.meta.env.VITE_ERC_ADDRESS
|
||||||
|
var CFNFTAddress = import.meta.env.VITE_CFNFT_ADDRESS
|
||||||
|
var claimAddress = import.meta.env.VITE_CLAIM_ADDRESS
|
||||||
|
var claimWlAddress = import.meta.env.VITE_CLAIMWL_ADDRESS
|
||||||
|
var chainId = import.meta.env.VITE_TOKENID_ID
|
||||||
|
// var connectUrl = process.env.VUE_APP_CONFIG_URL
|
||||||
|
console.log(CFNFTAddress,claimAddress,chainId)
|
||||||
|
|
||||||
|
// 公用方法
|
||||||
|
const MINT_CONTRACT_ADDRESS='0x31f29c9a3d0c1c13c825475aebf0d964b5b47c45'
|
||||||
|
const RPC='https://rpc.testnet.immutable.com/'
|
||||||
|
|
||||||
|
const requestChain = async (rpc, method, params) => {
|
||||||
|
const data = {
|
||||||
|
id: Date.now(),
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method,
|
||||||
|
params,
|
||||||
|
}
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
}
|
||||||
|
return fetch(rpc, options, DEFAULT_TIMEOUT).then(res => res.json())
|
||||||
|
}
|
||||||
|
const queryMintData = async(user, data) => {
|
||||||
|
const params = [{
|
||||||
|
from: user,
|
||||||
|
to: MINT_CONTRACT_ADDRESS,
|
||||||
|
data,
|
||||||
|
}, 'latest']
|
||||||
|
return requestChain(RPC, 'eth_call', params)
|
||||||
|
}
|
||||||
|
|
||||||
|
// const checkoutSDK = new checkout.Checkout()
|
||||||
|
// const type = checkout.WalletFilterTypes.ALL;
|
||||||
|
// window.addEventListener('load', function() {
|
||||||
|
// const passportInstance = new passport.Passport({
|
||||||
|
// baseConfig: {
|
||||||
|
// environment: config.Environment.SANDBOX, // or Environment.PRODUCTION
|
||||||
|
// publishableKey: 'wc:b348768c53d32b69062adcc7f67b263f771564c39edc06acc4cb3e9ee561d415@2?relay-protocol=irn&symKey=b8302aed25de3f9e3485eb8601d27c52779ab28cd8b1398312aa18be01cebbe8', // replace with your publishable API key from Hub
|
||||||
|
// // publishableKey: '', // replace with your publishable API key from Hub
|
||||||
|
// },
|
||||||
|
// clientId: 'eWbQF3aPY83RCNBMYGv2wUAbOJFKZo8l', // replace with your client ID from Hub
|
||||||
|
// redirectUri: 'http://localhost:5173/', // replace with one of your redirect URIs from Hub
|
||||||
|
// logoutRedirectUri: 'http://localhost:5173/', // replace with one of your logout URIs from Hub
|
||||||
|
// audience: '',
|
||||||
|
// scope: 'openid offline_access email transact',
|
||||||
|
// popupOverlayOptions: {
|
||||||
|
// disableGenericPopupOverlay: false, // Set to true to disable the generic pop-up overlay
|
||||||
|
// disableBlockedPopupOverlay: false, // Set to true to disable the blocked pop-up overlay
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// passportInstance.loginCallback();
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
const passportInstance = new passport.Passport({
|
||||||
|
baseConfig: {
|
||||||
|
environment: config.Environment.SANDBOX, // or Environment.PRODUCTION
|
||||||
|
publishableKey: 'pk_imapik-test-1E-detBXtG7U$5961WuL', // replace with your publishable API key from Hub
|
||||||
|
// publishableKey: '', // replace with your publishable API key from Hub
|
||||||
|
},
|
||||||
|
clientId: 'gYQrjtct7CN4UVwDG2sb8yACfYRo3xQJ', // replace with your client ID from Hub
|
||||||
|
redirectUri: 'http://localhost:5173/redirect', // replace with one of your redirect URIs from Hub
|
||||||
|
logoutRedirectUri: 'http://localhost:5173/logout', // replace with one of your logout URIs from Hub
|
||||||
|
audience: 'platform_api',
|
||||||
|
scope: 'openid offline_access email transact',
|
||||||
|
popupOverlayOptions: {
|
||||||
|
disableGenericPopupOverlay: true, // Set to true to disable the generic pop-up overlay
|
||||||
|
disableBlockedPopupOverlay: true, // Set to true to disable the blocked pop-up overlay
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 链接Wallet Connect钱包
|
||||||
|
export async function getConnect() {
|
||||||
|
const passportProvider = proxy.$passportInit;
|
||||||
|
const accounts = await passportProvider.request({ method: "eth_requestAccounts" })
|
||||||
|
console.log( accounts,'-----------------------------------------------------------------')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getLogout() {
|
||||||
|
const profile = await passportInstance.logout();
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function linkWallet(val) {
|
||||||
|
let res
|
||||||
|
if(val == 'ethereum') {
|
||||||
|
const web3js = window.ethereum
|
||||||
|
if (typeof web3js !== "undefined") {
|
||||||
|
res = await ethereum.request({ method: "eth_requestAccounts" })
|
||||||
|
}
|
||||||
|
} else if(val == 'okxwallet') {
|
||||||
|
res = await okxwallet.request({ method: "eth_requestAccounts" });
|
||||||
|
}
|
||||||
|
return res[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function disconnectLink(name) {
|
||||||
|
if(name == 'ethereum') {
|
||||||
|
await window.ethereum.request({
|
||||||
|
"method": "wallet_revokePermissions",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"eth_accounts": {}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
} else if(name == 'okxwallet') {
|
||||||
|
await okxwallet.request({
|
||||||
|
"method": "wallet_disconnect",
|
||||||
|
})
|
||||||
|
} else if(name == 'connect') {
|
||||||
|
await passportInstance.logout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Wallet Connect初始化
|
||||||
|
// import { EthereumProvider } from '@walletconnect/ethereum-provider'
|
||||||
|
// const provider = await EthereumProvider.init({
|
||||||
|
// projectId: 'e7743d46923911fa8850619b7a7f6d9d', // required
|
||||||
|
// chains: ['1'], // required
|
||||||
|
// showQrModal: true, // requires @walletconnect/modal
|
||||||
|
// optionalChains: ['1'],
|
||||||
|
// // optionalMethods: ['eth_signTypedData', 'eth_signTypedData_v4'],
|
||||||
|
// metadata: {
|
||||||
|
// name: 'Counter Fire',
|
||||||
|
// description: 'Counter Fire',
|
||||||
|
// url: 'https://mint.counterfire.games/',
|
||||||
|
// icons: ['https://www.counterfire.games/favicon.ico'],
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// 链接Wallet Connect钱包
|
||||||
|
// export async function getConnect() {
|
||||||
|
// await provider.connect()
|
||||||
|
// let result = await provider.request({ method: 'eth_requestAccounts' })
|
||||||
|
// return result
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 获取钱包地址
|
||||||
|
export async function getWalletAddress() {
|
||||||
|
const web3js = window.ethereum
|
||||||
|
const web3 = await web3js.request({
|
||||||
|
method: 'eth_accounts'
|
||||||
|
})
|
||||||
|
if (web3 !== 'undefined') {
|
||||||
|
if (web3[0] == '') {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return await web3[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看钱包是否链接
|
||||||
|
export async function isWalletConnected() {
|
||||||
|
const ethereum = window.web3;
|
||||||
|
if (typeof ethereum !== 'undefined') {
|
||||||
|
let res = await ethereum.request({ method: "eth_accounts" })
|
||||||
|
// await okxwallet.request({ method: "eth_accounts" });
|
||||||
|
// console.log(res,'279-----')
|
||||||
|
if(res[0] == '') {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有arbitrum-sepolia网络
|
||||||
|
export async function isSepoliNetwork(name,web3) {
|
||||||
|
let res
|
||||||
|
if(name == 'ethereum') {
|
||||||
|
res = await window.ethereum.request({
|
||||||
|
method: "wallet_switchEthereumChain",
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
chainId: chainId
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
return false
|
||||||
|
} else if(name == 'okxwallet') {
|
||||||
|
res =
|
||||||
|
await window.ethereum.request({
|
||||||
|
method: "wallet_switchEthereumChain",
|
||||||
|
params: [
|
||||||
|
{
|
||||||
|
chainId: chainId
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
return false
|
||||||
|
} else if(name == 'connect') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加arbitrum-sepolia网络
|
||||||
|
export async function addNetwork(name) {
|
||||||
|
if(name == 'ethereum') {
|
||||||
|
try{
|
||||||
|
let res = await window.ethereum.request({
|
||||||
|
method: 'wallet_addEthereumChain',
|
||||||
|
params: [{
|
||||||
|
chainId: chainId,
|
||||||
|
chainName: 'Sepolia Testnet Explorer',
|
||||||
|
rpcUrls: ['https://rpc.testnet.immutable.com'],
|
||||||
|
iconUrls: ['https://xdaichain.com/fake/example/url/xdai.png'],
|
||||||
|
blockExplorerUrls: ['https://rpc.testnet.immutable.com'],
|
||||||
|
nativeCurrency: {
|
||||||
|
name: "TIMX",
|
||||||
|
symbol: "TIMX",
|
||||||
|
decimals: 18
|
||||||
|
},
|
||||||
|
},]
|
||||||
|
})
|
||||||
|
return await res
|
||||||
|
} catch(e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else if(name == 'okxwallet') {
|
||||||
|
try{
|
||||||
|
let res = await okxwallet.request({
|
||||||
|
method: 'wallet_addEthereumChain',
|
||||||
|
params: [{
|
||||||
|
chainId: chainId,
|
||||||
|
chainName: 'Sepolia Testnet Explorer',
|
||||||
|
rpcUrls: ['https://rpc.testnet.immutable.com'],
|
||||||
|
iconUrls: ['https://xdaichain.com/fake/example/url/xdai.png'],
|
||||||
|
blockExplorerUrls: ['https://rpc.testnet.immutable.com'],
|
||||||
|
nativeCurrency: {
|
||||||
|
name: "TIMX",
|
||||||
|
symbol: "TIMX",
|
||||||
|
decimals: 18
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
return await res
|
||||||
|
} catch(e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else if(name == 'connect') {
|
||||||
|
try{
|
||||||
|
let res = await window.provider.request({
|
||||||
|
method: 'wallet_addEthereumChain',
|
||||||
|
params: [{
|
||||||
|
chainId: '0xaa36a7',
|
||||||
|
chainName: 'Sepolia Testnet Explorer',
|
||||||
|
rpcUrls: ['https://sepolia.infura.io/v3'],
|
||||||
|
iconUrls: ['https://xdaichain.com/fake/example/url/xdai.png'],
|
||||||
|
blockExplorerUrls: ['https://sepolia.etherscan.io'],
|
||||||
|
nativeCurrency: {
|
||||||
|
name: "TIMX",
|
||||||
|
symbol: "TIMX",
|
||||||
|
decimals: 18
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
return await res
|
||||||
|
} catch(e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const GAS_BOOST = 2
|
||||||
|
|
||||||
|
// claim NFT
|
||||||
|
export const claimStage2Nft = async(name, myAddress, params, web3) => {
|
||||||
|
let price = params*1e18
|
||||||
|
if(name == 'connect') {
|
||||||
|
let gasPrice = await web3.request({ method: 'eth_gasPrice' })
|
||||||
|
let web3Provider = new providers.Web3Provider(web3)
|
||||||
|
const signer = web3Provider.getSigner();
|
||||||
|
const [ userAddress ] = await web3.request({ method: "eth_requestAccounts"});
|
||||||
|
const contractFT = new ethers.Contract(ERCAddress, abis['ERC'].abi, signer);
|
||||||
|
// let gasApprove = await contractFT.estimateGas.approve(claimWlAddress, window.BigInt(price))
|
||||||
|
let gasApprove = await contractFT.estimateGas.approve(claimWlAddress, price)
|
||||||
|
gasApprove = (parseInt(gasApprove) * GAS_BOOST) | 0;
|
||||||
|
// await contractFT.approve(claimWlAddress, window.BigInt(price))
|
||||||
|
await contractFT.approve(claimWlAddress, price)
|
||||||
|
|
||||||
|
//------
|
||||||
|
const contract = new ethers.Contract(claimWlAddress, abis['CLAIMWL'].abi, signer);
|
||||||
|
// console.log(params, '--------------',contract);
|
||||||
|
// return
|
||||||
|
let gas = await contract.estimateGas.claim(params)
|
||||||
|
// console.log(gas)
|
||||||
|
// return
|
||||||
|
return await contract.claim(params)
|
||||||
|
|
||||||
|
let res = await web3.request({ method: 'eth_gasPrice' })
|
||||||
|
console.log(params[1], res)
|
||||||
|
let abc = await web3.request({ method: 'eth_requestAccounts'})
|
||||||
|
// let contractFT = await web3.request({ method: 'eth_call',
|
||||||
|
// params: [
|
||||||
|
// {
|
||||||
|
// to: myAddress,
|
||||||
|
// data: claimAddress
|
||||||
|
// },
|
||||||
|
// 'latest'
|
||||||
|
// ]
|
||||||
|
// })
|
||||||
|
} else {
|
||||||
|
// const account = await web3.eth.getAccounts()
|
||||||
|
let res = await isSepoliNetwork(name,web3)
|
||||||
|
if(!res) {
|
||||||
|
let addRes = await addNetwork(name,web3)
|
||||||
|
}
|
||||||
|
const gasPrice = await web3.eth.getGasPrice()
|
||||||
|
const contractFT = new web3.eth.Contract(abis['ERC'].abi, ERCAddress, {
|
||||||
|
from: myAddress
|
||||||
|
});
|
||||||
|
const allowance = await contractFT.methods.allowance(myAddress, claimWlAddress).call()
|
||||||
|
console.log('allowance', allowance)
|
||||||
|
// if (parseInt(allowance) < params) {
|
||||||
|
let gasApprove = await contractFT.methods.approve(claimWlAddress, price).estimateGas();
|
||||||
|
gasApprove = (parseInt(gasApprove) * GAS_BOOST) | 0;
|
||||||
|
await contractFT.methods.approve(claimWlAddress, price).send({ gas: gasApprove, gasPrice });
|
||||||
|
// }
|
||||||
|
// return
|
||||||
|
const contract = new web3.eth.Contract(abis['CLAIMWL'].abi, claimWlAddress, {
|
||||||
|
from: myAddress
|
||||||
|
});
|
||||||
|
let gas = await contract.methods.claim(params).estimateGas()
|
||||||
|
gas = (parseInt(gas) * GAS_BOOST) | 0;
|
||||||
|
// let abc = await contract.methods.claim(params).send({gas, gasPrice})
|
||||||
|
// console.log(abc)
|
||||||
|
return contract.methods.claim(params).send({gas, gasPrice})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 查询已Mint NFT数量
|
||||||
|
export const balanceOfAmount = async(name, myAddress) => {
|
||||||
|
let web3
|
||||||
|
if(name == 'ethereum') {
|
||||||
|
web3 = new Web3(window.ethereum);
|
||||||
|
} else if(name == 'okxwallet') {
|
||||||
|
web3 = new Web3(okxwallet)
|
||||||
|
} else if(name == 'connect') {
|
||||||
|
web3 = new Web3(provider)
|
||||||
|
}
|
||||||
|
let contract = new web3.eth.Contract(abis['CLAIM'].abi, claimAddress, { from: myAddress})
|
||||||
|
const tokenId = await contract.methods.totalCount(myAddress).call();
|
||||||
|
return parseInt(tokenId)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// mint配置
|
||||||
|
export const mintConfig = async(name, myAddress) => {
|
||||||
|
let web3
|
||||||
|
if(name == 'ethereum') {
|
||||||
|
web3 = new Web3(window.ethereum);
|
||||||
|
} else if(name == 'okxwallet') {
|
||||||
|
web3 = new Web3(okxwallet)
|
||||||
|
} else if(name == 'connect') {
|
||||||
|
web3 = new Web3(provider)
|
||||||
|
}
|
||||||
|
let contract = new web3.eth.Contract(abis['CLAIM'].abi, claimAddress, { from: myAddress})
|
||||||
|
const mintArr = await contract.methods.mintConfig(myAddress).call();
|
||||||
|
return mintArr
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前用户白单数量
|
||||||
|
export const fetchWLCount = async(name, myAddress) => {
|
||||||
|
let web3
|
||||||
|
if(name == 'ethereum') {
|
||||||
|
web3 = new Web3(window.ethereum);
|
||||||
|
} else if(name == 'okxwallet') {
|
||||||
|
web3 = new Web3(okxwallet)
|
||||||
|
} else if(name == 'connect') {
|
||||||
|
web3 = new Web3(provider)
|
||||||
|
}
|
||||||
|
let contract = new web3.eth.Contract(abis['CLAIMWL'].abi, claimWlAddress, { from: myAddress})
|
||||||
|
const tokenId = await contract.methods.whiteCount(myAddress).call();
|
||||||
|
return parseInt(tokenId)
|
||||||
|
|
||||||
|
const data = '0xe65ee803'
|
||||||
|
return queryMintData(user, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前用户已获得的数量
|
||||||
|
export const fetchMintedCount = async (name, myAddress) => {
|
||||||
|
let web3
|
||||||
|
if(name == 'ethereum') {
|
||||||
|
web3 = new Web3(window.ethereum);
|
||||||
|
} else if(name == 'okxwallet') {
|
||||||
|
web3 = new Web3(okxwallet)
|
||||||
|
} else if(name == 'connect') {
|
||||||
|
web3 = new Web3(provider)
|
||||||
|
}
|
||||||
|
let contract = new web3.eth.Contract(abis['CLAIMWL'].abi, claimWlAddress, { from: myAddress})
|
||||||
|
const tokenId = await contract.methods.mintedNft(myAddress).call();
|
||||||
|
console.log(tokenId)
|
||||||
|
return tokenId
|
||||||
|
|
||||||
|
const data = '0xe65ee803'
|
||||||
|
return queryMintData(user, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// passport send()
|
||||||
|
|
||||||
|
const returnSend = async (web3, ERCAddress, contractAddress, abi, data) => {
|
||||||
|
// let gasPrice = await web3.request({ method: 'eth_gasPrice' })
|
||||||
|
let web3Provider = new providers.Web3Provider(web3)
|
||||||
|
const signer = web3Provider.getSigner();
|
||||||
|
const contract = new ethers.Contract(ERCAddress, abi, signer);
|
||||||
|
let gasApprove = await contract.estimateGas.approve(contractAddress, data)
|
||||||
|
// let gasApprove = tx
|
||||||
|
gasApprove = (parseInt(gasApprove) * GAS_BOOST) | 0;
|
||||||
|
console.log(parseInt(gasApprove),'---')
|
||||||
|
return contract.approve(contractAddress, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
24
src/wallet/initPassport.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { config, passport } from '@imtbl/sdk';
|
||||||
|
const passportInstance = new passport.Passport({
|
||||||
|
baseConfig: {
|
||||||
|
environment: config.Environment.SANDBOX, // or Environment.PRODUCTION
|
||||||
|
publishableKey: 'pk_imapik-test-1E-detBXtG7U$5961WuL', // replace with your publishable API key from Hub
|
||||||
|
// publishableKey: '', // replace with your publishable API key from Hub
|
||||||
|
},
|
||||||
|
clientId: 'gYQrjtct7CN4UVwDG2sb8yACfYRo3xQJ', // replace with your client ID from Hub
|
||||||
|
redirectUri: 'http://localhost:5173/redirect', // replace with one of your redirect URIs from Hub
|
||||||
|
logoutRedirectUri: 'http://localhost:5173/logout', // replace with one of your logout URIs from Hub
|
||||||
|
audience: 'platform_api',
|
||||||
|
scope: 'openid offline_access email transact',
|
||||||
|
popupOverlayOptions: {
|
||||||
|
disableGenericPopupOverlay: true, // Set to true to disable the generic pop-up overlay
|
||||||
|
disableBlockedPopupOverlay: true, // Set to true to disable the blocked pop-up overlay
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const passportInit = app => {
|
||||||
|
app.component('passportInit',passportInstance)
|
||||||
|
app.config.globalProperties.$passportInit = passportInstance
|
||||||
|
// app.provide('passportInit', passportInit)
|
||||||
|
}
|
||||||
|
passportInstance.loginCallback()
|
||||||
|
export default passportInit
|
59
vite.config.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import {nodePolyfills} from 'vite-plugin-node-polyfills'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
nodePolyfills({
|
||||||
|
globals: {
|
||||||
|
Buffer: false
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
base: './',
|
||||||
|
// build: {
|
||||||
|
// // 打包输出目录
|
||||||
|
// outDir: 'dist',
|
||||||
|
// // 打包文件名
|
||||||
|
// assetsDir: 'static',
|
||||||
|
// sourcemap: false, // 禁用源映射
|
||||||
|
// // 静态资源引用路径
|
||||||
|
// assetsPublicPath: '/',
|
||||||
|
// // 是否开启压缩
|
||||||
|
// minify: 'terser',
|
||||||
|
// // 分离代码
|
||||||
|
// // splitChunks: {},
|
||||||
|
// // 环境变量
|
||||||
|
// env: {
|
||||||
|
// BASE_URL: process.env.VITE_API_BASE_URL
|
||||||
|
// },
|
||||||
|
// rollupOptions: {
|
||||||
|
// plugins: [nodePolyfills()],
|
||||||
|
// },
|
||||||
|
// commonjsOptions: {
|
||||||
|
// transformMixedEsModules: true,
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
define: {
|
||||||
|
global: {},
|
||||||
|
'process.env': {}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 5173, // 设置服务启动端口号
|
||||||
|
open: false, // 设置服务启动时是否自动打开浏览器
|
||||||
|
cors: true, // 允许跨域
|
||||||
|
// host: 'localhost', //
|
||||||
|
hmr:true,
|
||||||
|
// 设置代理,根据我们项目实际情况配置
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: process.env.VITE_BASE_API, // 将 /api 开头的请求代理到该地址
|
||||||
|
changeOrigin: true,
|
||||||
|
secure: false,
|
||||||
|
rewrite: (path) => path.replace('/api/', '/')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|