移除web3modal, 修改登陆逻辑

This commit is contained in:
cebgcontract 2022-03-04 19:08:04 +08:00
parent 340f199a3e
commit 5f2ad57784
13 changed files with 761 additions and 95 deletions

View File

@ -1,5 +1,5 @@
VUE_APP_WALLET_INFURAID='e7743d46923911fa8850619b7a7f6d9d' VUE_APP_WALLET_INFURAID='e7743d46923911fa8850619b7a7f6d9d'
VUE_APP_BASE_API='https://market-test.kingsome.cn' VUE_APP_BASE_API='https://market.cebg.games'
VUE_APP_CHAIN_ID=322 VUE_APP_CHAIN_ID=322
VUE_APP_CHAIN_RPC='https://rpc-testnet.kcc.network' VUE_APP_CHAIN_RPC='https://rpc-testnet.kcc.network'
VUE_APP_CHAIN_NAME='KCC-TESTNET' VUE_APP_CHAIN_NAME='KCC-TESTNET'

6
src/cebg.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
interface Window {
ethereum: any
web3: any
celo: any
}
declare let window: Window

File diff suppressed because one or more lines are too long

View File

@ -44,20 +44,24 @@
</div> </div>
<div class="copy-right"> <div class="copy-right">
Copyright &copy; CEBG. All rights reserved. Copyright &copy; CEBG. All rights reserved.
<chain-modal></chain-modal>
</div> </div>
</footer> </footer>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator' import { Component, Vue } from 'vue-property-decorator'
import ChainModal from '@/components/core/ChainModal.vue'
@Component({ @Component({
name: 'DesktopFooter', name: 'DesktopFooter',
components: { components: {
ChainModal
} }
}) })
export default class extends Vue { export default class extends Vue {
private chainModalShow = true
} }
</script> </script>

274
src/configs/allchain.ts Normal file
View File

@ -0,0 +1,274 @@
export const AllChains = [
{
name: 'Ethereum Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.ankr.com/eth',
id: '1',
symbol: 'ETH',
explorerurl: 'https://etherscan.io'
},
{
name: 'Ethereum Ropsten Testnet RPC',
type: 'Testnet',
rpc: 'https://ropsten.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161',
id: '3',
symbol: 'ETH',
explorerurl: 'https://ropsten.etherscan.io'
},
{
name: 'Ethereum Rinkeby Testnet RPC',
type: 'Testnet',
rpc: 'https://rinkey.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161',
id: '4',
symbol: 'ETH',
explorerurl: 'https://rinkey.etherscan.io'
},
{
name: 'Ethereum Goerli Testnet RPC',
type: 'Testnet',
rpc: 'https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161',
id: '5',
symbol: 'ETH',
explorerurl: 'https://goerli.etherscan.io'
},
{
name: 'Ethereum Kovan Testnet RPC',
type: 'Testnet',
rpc: 'https://kovan.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161',
id: '6',
symbol: 'ETH',
explorerurl: 'https://kovan.etherscan.io'
},
{
name: 'Ubiq Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.octano.dev/',
id: '8',
symbol: 'UBQ',
explorerurl: 'https://ubiqscan.io/'
},
{
name: 'Elastos ETH Mainnet RPC',
type: 'Mainnet',
rpc: 'https://api.elastos.io/eth',
id: '20',
symbol: 'ELA',
explorerurl: 'https://explorer.elaeth.io/'
},
{
name: 'Cronos Mainnet RPC',
type: 'Mainnet',
rpc: 'https://evm-cronos.crypto.org',
id: '25',
symbol: 'CRO',
explorerurl: 'https://cronos.crypto.org/explorer/'
},
{
name: 'Telos EVM Mainnet RPC',
type: 'Mainnet',
rpc: 'https://mainnet.telos.net/evm',
id: '40',
symbol: 'TLOS',
explorerurl: 'https://telos.net/'
},
{
name: 'Binance Smart Chain Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.ankr.com/bsc',
id: '56',
symbol: 'BNB',
explorerurl: 'https://bscscan.com'
},
{
name: 'OKExChain Mainnet RPC',
type: 'Mainnet',
rpc: 'https://exchainrpc.okex.org',
id: '66',
symbol: 'OKT',
explorerurl: 'https://www.oklink.com/okexchain'
},
{
name: 'Hoo Mainnet RPC',
type: 'Mainnet',
rpc: 'https://http-mainnet.hoosmartchain.com',
id: '70',
symbol: 'HOO',
explorerurl: 'https://hooscan.com'
},
{
name: 'Binance Smart Chain Testnet RPC',
type: 'Testnet',
rpc: 'https://data-seed-prebsc-1-s1.binance.org:8545/',
id: '97',
symbol: 'BNB',
explorerurl: 'https://testnet.bscscan.com'
},
{
name: 'xDai Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.xdaichain.com/',
id: '100',
symbol: 'XDAI',
explorerurl: 'https://blockscout.com/xdai/mainnet/'
},
{
name: 'Fuse Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.fuse.io',
id: '122',
symbol: 'FUSE',
explorerurl: 'https://explorer.fuse.io/'
},
{
name: 'HECO Mainnet RPC',
type: 'Mainnet',
rpc: 'https://http-mainnet-node.huobichain.com/',
id: '128',
symbol: 'HT',
explorerurl: 'https://hecoinfo.com/'
},
{
name: 'Matic Mainnet RPC',
type: 'Mainnet',
rpc: 'https://polygon-rpc.com',
id: '137',
symbol: 'MATIC',
explorerurl: 'https://explorer.matic.network/'
},
{
name: 'Fantom Opera Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.ftm.tools/',
id: '250',
symbol: 'FTM',
explorerurl: 'https://ftmscan.com'
},
{
name: 'HECO Testnet RPC',
type: 'Testnet',
rpc: 'https://http-testnet.hecochain.com',
id: '256',
symbol: 'HT',
explorerurl: 'https://testnet.hecoinfo.com/'
},
{
name: 'KCC Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc-mainnet.kcc.network',
id: '321',
symbol: 'KCS',
explorerurl: 'https://scan.kcc.network'
},
{
name: 'KCC Testnet RPC',
type: 'Testnet',
rpc: 'https://scan-testnet.kcc.network',
id: '322',
symbol: 'tKCS',
explorerurl: 'https://scan-testnet.kcc.network'
},
{
name: 'Moonriver Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.moonriver.moonbeam.network',
id: '1285',
symbol: 'MOVR',
explorerurl: 'https://blockscout.moonriver.moonbeam.network/'
},
{
name: 'Fantom Testnet RPC',
type: 'Testnet',
rpc: 'https://rpc.testnet.fantom.network/',
id: '4002',
symbol: 'FTM',
explorerurl: 'https://testnet.ftmscan.com'
},
{
name: 'IoTeX Mainnet RPC',
type: 'Mainnet',
rpc: 'https://babel-api.mainnet.iotex.io',
id: '4689',
symbol: 'IOTEX',
explorerurl: 'https://iotexscan.io/'
},
{
name: 'Nahmii Mainnet RPC',
type: 'Mainnet',
rpc: 'https://l2.nahmii.io/',
id: '5551',
symbol: 'ETH',
explorerurl: 'https://explorer.nahmii.io/'
},
{
name: 'Nahmii Testnet RPC',
type: 'Testnet',
rpc: 'https://l2.testnet.nahmii.io/',
id: '5553',
symbol: 'ETH',
explorerurl: 'https://explorer.testnet.nahmii.io/'
},
{
name: 'Arbitrum Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.ankr.com/arbitrum',
id: '42161',
symbol: 'ETH',
explorerurl: 'https://arbiscan.io/'
},
{
name: 'Celo Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.ankr.com/celo',
id: '42220',
symbol: 'CELO',
explorerurl: 'https://celoscan.com'
},
{
name: 'Avalanche C Chain Local RPC',
type: 'Testnet',
rpc: 'https://localhost:9650/ext/bc/C/rpc',
id: '43112',
symbol: 'AVAX',
explorerurl: 'https://snowtrace.io'
},
{
name: 'Avalanche FUJI Testnet RPC',
type: 'Testnet',
rpc: 'https://api.avax-test.network/ext/bc/C/rpc',
id: '43113',
symbol: 'AVAX',
explorerurl: 'https://testnet.explorer.avax.network/'
},
{
name: 'Avalanche C Chain Mainnet RPC',
type: 'Mainnet',
rpc: 'https://rpc.ankr.com/avalanche',
id: '43114',
symbol: 'AVAX',
explorerurl: 'https://snowtrace.io'
},
{
name: 'Matic Testnet RPC',
type: 'Testnet',
rpc: 'https://rpc-mumbai.maticvigil.com',
id: '80001',
symbol: 'MATIC',
explorerurl: 'https://mumbai.polygonscan.com/'
},
{
name: 'Harmony Mainnet RPC',
type: 'Mainnet',
rpc: 'https://api.harmony.one/',
id: '1666600000',
symbol: 'ONE',
explorerurl: 'https://explorer.harmony.one'
},
{
name: 'Harmony Testnet RPC',
type: 'Testnet',
rpc: 'https://api.s0.b.hmny.io/',
id: '1666700000',
symbol: 'ONE',
explorerurl: 'https://explorer.harmony.one'
}
]

59
src/configs/chains.ts Normal file
View File

@ -0,0 +1,59 @@
const env = process.env.NODE_ENV || 'development'
export interface IChainData{
id: number
name: string
logo: string
rpc: string
explorerurl: string
symbol: string
decimals: number
type: string
}
export const chainMap: Map<string, IChainData[]> = new Map([
['development', [
{
type: 'development',
id: 322,
name: 'KCC-TESTNET',
logo: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzMiAzMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzIgMzI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojMDA5M0REO30KCS5zdDF7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRkZGRkZGO30KPC9zdHlsZT4KPGc+Cgk8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTEzLjUsMTZsNS4yLDUuM0wyMiwxOGMwLjYtMC42LDEuNS0wLjYsMiwwYzAsMCwwLDAsMCwwYzAuNiwwLjYsMC42LDEuNiwwLDIuMmwtNC4zLDQuNAoJCWMtMC42LDAuNi0xLjUsMC42LTIuMSwwYzAsMCwwLDAsMCwwbC02LjItNi40VjIyYzAsMC44LTAuNywxLjUtMS41LDEuNWMtMC44LDAtMS41LTAuNy0xLjUtMS41VjEwYzAtMC44LDAuNy0xLjUsMS41LTEuNQoJCWMwLjgsMCwxLjUsMC43LDEuNSwxLjV2My44bDYuMi02LjRjMC42LTAuNiwxLjUtMC42LDIuMSwwYzAsMCwwLDAsMCwwbDQuMyw0LjRjMC42LDAuNiwwLjYsMS42LDAsMi4yYy0wLjYsMC42LTEuNSwwLjYtMiwwCgkJYzAsMCwwLDAsMCwwbC0zLjMtMy40TDEzLjUsMTZ6IE0xOC43LDE0LjVjMC44LDAsMS41LDAuNywxLjUsMS41cy0wLjcsMS41LTEuNSwxLjVzLTEuNS0wLjctMS41LTEuNQoJCUMxNy4yLDE1LjIsMTcuOSwxNC41LDE4LjcsMTQuNXoiLz4KPC9nPgo8L3N2Zz4K',
rpc: 'https://rpc-testnet.kcc.network',
explorerurl: 'https://scan-testnet.kcc.network',
symbol: 'KCS',
decimals: 18
},
{
type: 'development',
id: 97,
name: 'BSC Testnet',
logo: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCAyMDAwIDIwMDAiPjxnIGZpbGw9IiNmM2JhMmYiPjxwYXRoIGQ9Ik02MTEuNTkgODQwLjQybDM4OC40LTM4OC4zOSAzODguNiAzODguNTkgMjI2LTIyNkw5OTkuOTkgMCAzODUuNiA2MTQuNDJsMjI1Ljk5IDIyNk0uMDA2IDk5OS45NjlsMjI2LjAwNy0yMjYuMDA3IDIyNS45OTIgMjI1Ljk5M0wyMjYgMTIyNS45NnpNNjExLjU5IDExNTkuNThsMzg4LjQgMzg4LjM5IDM4OC41OS0zODguNTggMjI2LjEyIDIyNS44OC0uMTEuMTJMOTk5Ljk5IDIwMDBsLTYxNC40MS02MTQuNC0uMzItLjMyIDIyNi4zMy0yMjUuN00xNTQ4LjAxMyAxMDAwLjA5M2wyMjYuMDA3LTIyNi4wMDYgMjI1Ljk5MiAyMjUuOTkyLTIyNi4wMDYgMjI2LjAwN3oiLz48cGF0aCBkPSJNMTIyOS4yMiA5OTkuODhoLjFMOTk5Ljk5IDc3MC41NSA4MzAuNTEgOTQwLjAzaC0uMDFsLTE5LjQ3IDE5LjQ4LTQwLjE2IDQwLjE3LS4zMi4zMS4zMi4zMyAyMjkuMTIgMjI5LjEzIDIyOS4zMy0yMjkuMzMuMTEtLjEzLS4yMS0uMTEiLz48L2c+PC9zdmc+',
rpc: 'https://data-seed-prebsc-1-s1.binance.org:8545/',
explorerurl: 'https://testnet.bscscan.com/',
symbol: 'BNB',
decimals: 18
}
]],
['production', [
{
type: 'production',
id: 321,
name: 'KCC-MAINNET',
logo: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDI0LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAzMiAzMiIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzIgMzI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojMDA5M0REO30KCS5zdDF7ZmlsbC1ydWxlOmV2ZW5vZGQ7Y2xpcC1ydWxlOmV2ZW5vZGQ7ZmlsbDojRkZGRkZGO30KPC9zdHlsZT4KPGc+Cgk8Y2lyY2xlIGNsYXNzPSJzdDAiIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTEzLjUsMTZsNS4yLDUuM0wyMiwxOGMwLjYtMC42LDEuNS0wLjYsMiwwYzAsMCwwLDAsMCwwYzAuNiwwLjYsMC42LDEuNiwwLDIuMmwtNC4zLDQuNAoJCWMtMC42LDAuNi0xLjUsMC42LTIuMSwwYzAsMCwwLDAsMCwwbC02LjItNi40VjIyYzAsMC44LTAuNywxLjUtMS41LDEuNWMtMC44LDAtMS41LTAuNy0xLjUtMS41VjEwYzAtMC44LDAuNy0xLjUsMS41LTEuNQoJCWMwLjgsMCwxLjUsMC43LDEuNSwxLjV2My44bDYuMi02LjRjMC42LTAuNiwxLjUtMC42LDIuMSwwYzAsMCwwLDAsMCwwbDQuMyw0LjRjMC42LDAuNiwwLjYsMS42LDAsMi4yYy0wLjYsMC42LTEuNSwwLjYtMiwwCgkJYzAsMCwwLDAsMCwwbC0zLjMtMy40TDEzLjUsMTZ6IE0xOC43LDE0LjVjMC44LDAsMS41LDAuNywxLjUsMS41cy0wLjcsMS41LTEuNSwxLjVzLTEuNS0wLjctMS41LTEuNQoJCUMxNy4yLDE1LjIsMTcuOSwxNC41LDE4LjcsMTQuNXoiLz4KPC9nPgo8L3N2Zz4K',
rpc: 'https://rpc-mainnet.kcc.network',
explorerurl: 'https://explorer.kcc.io',
symbol: 'KCS',
decimals: 18
},
{
type: 'production',
id: 32,
name: 'BSC',
logo: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNTAwIiBoZWlnaHQ9IjI1MDAiIHZpZXdCb3g9IjAgMCAyMDAwIDIwMDAiPjxnIGZpbGw9IiNmM2JhMmYiPjxwYXRoIGQ9Ik02MTEuNTkgODQwLjQybDM4OC40LTM4OC4zOSAzODguNiAzODguNTkgMjI2LTIyNkw5OTkuOTkgMCAzODUuNiA2MTQuNDJsMjI1Ljk5IDIyNk0uMDA2IDk5OS45NjlsMjI2LjAwNy0yMjYuMDA3IDIyNS45OTIgMjI1Ljk5M0wyMjYgMTIyNS45NnpNNjExLjU5IDExNTkuNThsMzg4LjQgMzg4LjM5IDM4OC41OS0zODguNTggMjI2LjEyIDIyNS44OC0uMTEuMTJMOTk5Ljk5IDIwMDBsLTYxNC40MS02MTQuNC0uMzItLjMyIDIyNi4zMy0yMjUuN00xNTQ4LjAxMyAxMDAwLjA5M2wyMjYuMDA3LTIyNi4wMDYgMjI1Ljk5MiAyMjUuOTkyLTIyNi4wMDYgMjI2LjAwN3oiLz48cGF0aCBkPSJNMTIyOS4yMiA5OTkuODhoLjFMOTk5Ljk5IDc3MC41NSA4MzAuNTEgOTQwLjAzaC0uMDFsLTE5LjQ3IDE5LjQ4LTQwLjE2IDQwLjE3LS4zMi4zMS4zMi4zMyAyMjkuMTIgMjI5LjEzIDIyOS4zMy0yMjkuMzMuMTEtLjEzLS4yMS0uMTEiLz48L2c+PC9zdmc+',
rpc: 'https://bsc-dataseed.binance.org',
explorerurl: 'https://www.bscscan.com',
symbol: 'BNB',
decimals: 18
}
]]
])
export const chains: () => IChainData[] = () => chainMap.get(env) || []

View File

@ -1,12 +1,13 @@
import Vue from 'vue' import Vue from 'vue'
import App from './App.vue' import App from './App.vue'
import { Loading, Message, MessageBox, Notification, Slider } from 'element-ui' import { Loading, Message, MessageBox, Notification, Slider, Tooltip } from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css' import 'element-ui/lib/theme-chalk/index.css'
import router from './router' import router from './router'
import store from './store' import store from './store'
Vue.use(Loading.directive) Vue.use(Loading.directive)
Vue.use(Slider) Vue.use(Slider)
Vue.use(Tooltip)
Vue.config.productionTip = false Vue.config.productionTip = false

View File

@ -4,21 +4,20 @@ import { getNonce } from '@/api/User'
import { AppModule } from '@/store/modules/app' import { AppModule } from '@/store/modules/app'
import { UserModule } from '@/store/modules/user' import { UserModule } from '@/store/modules/user'
import { Message } from 'element-ui' import { Message } from 'element-ui'
import { EventBus, NEED_NONCE } from '@/utils/event-bus'
@singleton @singleton
export default class ChainManager { export default class ChainManager {
bc: BlockChain bc: BlockChain
constructor() { constructor() {
this.bc = new BlockChain() this.bc = new BlockChain()
EventBus.$on(NEED_NONCE, this.checkNance.bind(this))
} }
public async init() { public async init() {
if (this.bc.isWalletConnect) { if (this.bc.isWalletConnect) {
try { try {
await this.bc.connect() await this.bc.connect()
if (!AppModule.nonce && !AppModule.step) {
await this.getNance()
}
} catch (err) { } catch (err) {
console.log('connect chain error: ', err) console.log('connect chain error: ', err)
} }
@ -36,17 +35,18 @@ export default class ChainManager {
public async login() { public async login() {
if (!AppModule.accountId) { if (!AppModule.accountId) {
try { try {
await this.bc.connect() await this.bc.connect(true)
} catch (err) { } catch (err) {
Message({ Message({
message: err.message, message: err.message,
type: 'error', type: 'error',
duration: 5 * 1000 duration: 5 * 1000
}) })
return
} }
} }
console.log(`AppModule.accountId: ${AppModule.accountId}, chainId: ${AppModule.chainId}`) }
public async checkNance() {
try { try {
let nonce = AppModule.nonce let nonce = AppModule.nonce
if (!nonce) { if (!nonce) {

View File

@ -1,12 +1,22 @@
import { singleton } from '@/decorators/singleton.decorator' import { singleton } from '@/decorators/singleton.decorator'
import WalletConnectProvider from '@walletconnect/web3-provider' import WalletConnectProvider from '@walletconnect/web3-provider'
import Web3Modal, { isMobile } from 'web3modal'
import { AppModule } from '@/store/modules/app' import { AppModule } from '@/store/modules/app'
import Web3 from 'web3' import Web3 from 'web3'
import { MessageBox } from 'element-ui' import { ERC20ABI, MALL_ADDRESS } from '@/configs/config_chain'
import { ERC20ABI, MALL_ADDRESS } from '@/utils/config_chain' import {
import { ACCOUNT_CHANGE, EventBus, NEED_LOGIN, NEED_NONCE } from '@/utils/event-bus' ACCOUNT_CHANGE,
CHAIN_SELECTED,
EventBus, NEED_CHANGE_CHAIN,
NEED_LOGIN,
NEED_NONCE,
SHOW_CHAIN_MODAL,
WALLET_SELECTED
} from '@/utils/event-bus'
import { UserModule } from '@/store/modules/user' import { UserModule } from '@/store/modules/user'
import { chains, IChainData } from '@/configs/chains'
import { isMobile } from '@/utils/resize'
import { hasMetamask } from '@/utils/chain.util'
import { AllChains } from '@/configs/allchain'
const EIP721_DOMAIN_DATA = [ const EIP721_DOMAIN_DATA = [
{ name: 'name', type: 'string' }, { name: 'name', type: 'string' },
@ -15,41 +25,34 @@ const EIP721_DOMAIN_DATA = [
{ name: 'verifyingContract', type: 'address' } { name: 'verifyingContract', type: 'address' }
] ]
const CACHE_KEY = 'cebg_chain_cache_key'
@singleton @singleton
export class BlockChain { export class BlockChain {
provider:any provider:any
web3: Web3 web3: Web3
web3Modal: Web3Modal currentChain = 0
// 0: null, 1: metamask, 2: walletconnect
walletType = 0
dataCached = false
coinInstanceMap: Map<string, any> coinInstanceMap: Map<string, any>
public chainMap: Map<number, IChainData> = new Map()
public rpc: any = {}
constructor() { constructor() {
const chainId = parseInt(process.env.VUE_APP_CHAIN_ID!) const chainDatas = chains()
this.coinInstanceMap = new Map() for (const data of chainDatas) {
AppModule.updateChainID(chainId) this.chainMap.set(data.id, data)
const rpc: any = { }
rpc[chainId] = process.env.VUE_APP_CHAIN_RPC!
const providerOptions = {
// binancechainwallet: {
// package: true
// },
walletconnect: {
package: WalletConnectProvider, // required
options: {
infuraId: process.env.VUE_APP_WALLET_INFURAID,
chainId,
rpc
}
}
} }
const disableInjectedProvider = isMobile() for (const d of AllChains) {
console.log('disableInjectedProvider: ', disableInjectedProvider) this.rpc[parseInt(d.id)] = d.rpc
this.web3Modal = new Web3Modal({ }
cacheProvider: true, // optional this.loadCachedProvider()
disableInjectedProvider, this.coinInstanceMap = new Map()
providerOptions // required // AppModule.updateChainID(chainId)
})
EventBus.$on(NEED_LOGIN, this.connect.bind(this)) EventBus.$on(NEED_LOGIN, this.connect.bind(this))
EventBus.$on(WALLET_SELECTED, this.walletSelected.bind(this))
EventBus.$on(CHAIN_SELECTED, this.chainSelected.bind(this))
} }
loadJson(url: string) { loadJson(url: string) {
@ -58,43 +61,117 @@ export class BlockChain {
} }
get isWalletConnect() { get isWalletConnect() {
return !!this.web3Modal.cachedProvider return !!this.walletType && !!this.currentChain
} }
public async connect() { public get hexChainId() {
try { return '0x' + this.currentChain.toString(16)
this.provider = await this.web3Modal.connect() }
this.subscribeToEvents()
this.web3 = new Web3(<any> this.provider) public async chainSelected(id: number) {
const accounts = await this.web3.eth.getAccounts() if (!this.chainMap.has(id)) {
const chainId = await this.web3.eth.getChainId() return
if (chainId !== AppModule.chainId) { }
try { this.currentChain = id
await MessageBox.confirm( if (this.provider) {
'You need to connect to supported network', await this.switchEthereumChain()
'Wrong Network', } else {
{ await this.connectWallet(true)
confirmButtonText: `Switch to ${process.env.VUE_APP_CHAIN_NAME} network`, }
cancelButtonText: 'Cancel', }
type: 'warning'
} public async walletSelected(type: number) {
) this.walletType = type
await this.switchEthereumChain() await this.connectWallet(true)
} catch (err) { }
return this.disconnect()
} public async connectWallet(isManual: boolean) {
} console.log('begin connect to wallet: ', this.walletType, this.currentChain)
if (accounts && accounts.length > 0) { if (this.walletType === 1) {
AppModule.updateAccount(accounts[0]) this.provider = await this.connectMetaMask()
} } else if (this.walletType === 2) {
AppModule.updateWalletStatus(true) this.provider = await this.connectWalletConnect()
console.log('chainId: ', chainId) }
console.log('accountsLogin: ', accounts, AppModule.accountId) if (!this.provider) {
return
}
this.web3 = new Web3(this.provider)
this.subscribeToEvents()
const chainId = await this.web3.eth.getChainId()
if (!this.chainMap.has(chainId)) {
EventBus.$emit(NEED_CHANGE_CHAIN)
return
}
const accounts = await this.web3.eth.getAccounts()
if (accounts && accounts.length > 0) {
AppModule.updateAccount(accounts[0])
}
this.saveProvider()
AppModule.updateChainID(chainId)
AppModule.updateWalletStatus(true)
console.log('current login chain: ', chainId)
console.log('accountsLogin: ', accounts, AppModule.accountId)
if (isManual) {
EventBus.$emit(NEED_NONCE) EventBus.$emit(NEED_NONCE)
return { account: accounts[0], chainId } } else {
AppModule.updateStep(1)
}
return { account: accounts[0], chainId }
}
public async connect(isManual = false) {
if (isMobile()) {
this.walletType = 2
} else {
if (hasMetamask()) {
if (isManual && !this.walletType) {
EventBus.$emit(SHOW_CHAIN_MODAL)
return
}
} else {
this.walletType = 2
}
}
if (this.isWalletConnect) {
await this.connectWallet(false)
} else {
EventBus.$emit(NEED_CHANGE_CHAIN)
}
}
public async connectMetaMask() {
let provider = null
if (typeof window.ethereum !== 'undefined') {
provider = window.ethereum
try {
await provider.request({ method: 'eth_requestAccounts' })
} catch (error) {
throw new Error('User Rejected')
}
} else if (window.web3) {
provider = window.web3.currentProvider
} else if (window.celo) {
provider = window.celo
} else {
throw new Error('No Web3 Provider found')
}
return provider
}
public async connectWalletConnect() {
const provider = new WalletConnectProvider({
infuraId: process.env.VUE_APP_WALLET_INFURAID,
chainId: 97,
rpc: this.rpc
})
try {
await provider.enable()
} catch (err) { } catch (err) {
console.log('connect to wallet connect error: ', err)
await Promise.reject(err) await Promise.reject(err)
} }
return provider
} }
private async initInstance(abi: any, address: string, account: string) { private async initInstance(abi: any, address: string, account: string) {
@ -115,15 +192,47 @@ export class BlockChain {
} }
} }
public clearCachedProvider() {
console.log('clear cached provider')
localStorage.removeItem(CACHE_KEY)
}
public loadCachedProvider() {
const dataStr = localStorage.getItem(CACHE_KEY)
if (dataStr) {
try {
const data = JSON.parse(dataStr)
this.walletType = data.walletType
if (this.chainMap.has(data.chainId)) {
this.currentChain = data.chainId
}
} catch (err) {
console.log('err parse cached json')
this.clearCachedProvider()
}
}
}
public saveProvider() {
const data = {
walletType: this.walletType,
chainId: this.currentChain
}
localStorage.setItem(CACHE_KEY, JSON.stringify(data))
}
public async disconnect() { public async disconnect() {
try { try {
await UserModule.LogOut() await UserModule.LogOut()
await this.provider?.disconnect() await this.provider?.disconnect()
this.currentChain = 0
this.walletType = 0
this.clearCachedProvider()
AppModule.updateStep(0) AppModule.updateStep(0)
AppModule.updateNonce('') AppModule.updateNonce('')
} catch (err) { } catch (err) {
} }
this.web3Modal.clearCachedProvider() this.clearCachedProvider()
AppModule.updateAccount('') AppModule.updateAccount('')
AppModule.updateWalletStatus(false) AppModule.updateWalletStatus(false)
} }
@ -146,20 +255,7 @@ export class BlockChain {
console.log('chainChanged', chainId) console.log('chainChanged', chainId)
const chainIdNum = parseInt(chainId) const chainIdNum = parseInt(chainId)
if (chainIdNum !== AppModule.chainId) { if (chainIdNum !== AppModule.chainId) {
try { EventBus.$emit(NEED_CHANGE_CHAIN)
await MessageBox.confirm(
'You need to connect to supported network',
'Wrong Network',
{
confirmButtonText: `Switch to ${process.env.VUE_APP_CHAIN_NAME} network`,
cancelButtonText: 'Cancel',
type: 'warning'
}
)
await this.switchEthereumChain()
} catch (err) {
return this.disconnect()
}
} }
}) })
@ -171,31 +267,33 @@ export class BlockChain {
async switchEthereumChain() { async switchEthereumChain() {
try { try {
await window.ethereum.request({ await this.provider.request({
method: 'wallet_switchEthereumChain', method: 'wallet_switchEthereumChain',
params: [{ chainId: AppModule.hexChainId }] params: [{ chainId: this.hexChainId }]
}) })
} catch (e: any) { } catch (e: any) {
console.log('switch chain error: ', e)
if (e.code === 4902) { if (e.code === 4902) {
try { try {
await window.ethereum.request({ const data = this.chainMap.get(this.currentChain)!
await this.provider.request({
method: 'wallet_addEthereumChain', method: 'wallet_addEthereumChain',
params: [ params: [
{ {
chainId: AppModule.hexChainId, chainId: this.hexChainId,
chainName: process.env.VUE_APP_CHAIN_NAME, chainName: data.name,
nativeCurrency: { nativeCurrency: {
name: process.env.VUE_APP_CHAIN_CURRENCY_NAME, name: data.symbol,
symbol: process.env.VUE_APP_CHAIN_CURRENCY_SYMBOL, symbol: data.symbol,
decimals: parseInt(process.env.VUE_APP_CHAIN_CURRENCY_DECIMALS!) decimals: data.decimals
}, },
blockExplorerUrls: [process.env.VUE_APP_CHAIN_EXPLORERURL], blockExplorerUrls: [data.explorerurl],
rpcUrls: [process.env.VUE_APP_CHAIN_RPC] rpcUrls: [data.rpc]
} }
] ]
}) })
} catch (addError) { } catch (addError) {
console.error(addError) console.error('add chain error: ', addError)
} }
} }
// console.error(e) // console.error(e)

20
src/utils/chain.util.ts Normal file
View File

@ -0,0 +1,20 @@
export function verifyInjectedProvider(check: string): boolean {
return window.ethereum
? window.ethereum[check]
: window.web3 &&
window.web3.currentProvider &&
window.web3.currentProvider[check]
}
/**
* check if there have metamask
* @return {boolean}
*/
export function hasMetamask(): boolean {
if (!!window.ethereum || !!window.web3) {
return verifyInjectedProvider('isMetaMask')
} else {
return false
}
}

View File

@ -14,3 +14,11 @@ export const NEED_LOGIN = 'need_login'
export const NEED_NONCE = 'need_nonce' export const NEED_NONCE = 'need_nonce'
export const ACCOUNT_CHANGE = 'account_change' export const ACCOUNT_CHANGE = 'account_change'
export const SHOW_CHAIN_MODAL = 'show_chain_modal'
export const NEED_CHANGE_CHAIN = 'need_change_chain'
export const WALLET_SELECTED = 'wallet_selected'
export const CHAIN_SELECTED = 'chain_selected'

View File

@ -11,6 +11,9 @@ module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/', publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
lintOnSave: process.env.NODE_ENV === 'development', lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false, productionSourceMap: false,
devServer: {
https: true
},
pwa: { pwa: {
name: name name: name
}, },