diff --git a/patches/@walletconnect+browser-utils+1.8.0.patch b/patches/@walletconnect+browser-utils+1.8.0.patch index 5e54023..bdc08bd 100644 --- a/patches/@walletconnect+browser-utils+1.8.0.patch +++ b/patches/@walletconnect+browser-utils+1.8.0.patch @@ -1,18 +1,28 @@ diff --git a/node_modules/@walletconnect/browser-utils/dist/esm/local.js b/node_modules/@walletconnect/browser-utils/dist/esm/local.js -index c7f4db3..9e2d455 100644 +index c7f4db3..9dd7e88 100644 --- a/node_modules/@walletconnect/browser-utils/dist/esm/local.js +++ b/node_modules/@walletconnect/browser-utils/dist/esm/local.js -@@ -1,26 +1,29 @@ +@@ -1,26 +1,39 @@ import { safeJsonParse, safeJsonStringify } from "./json"; import { getLocalStorage } from "./browser"; +var Cookies = require('js-cookie') ++ ++export const generateDomain = () => { ++ let host = location.host; ++ let hostArr = host.split("."); ++ if (host.length > 1) { ++ host = hostArr.slice(hostArr.length - 2).join("."); ++ } ++ return host; ++ }; ++ export function setLocal(key, data) { const raw = safeJsonStringify(data); - const local = getLocalStorage(); - if (local) { - local.setItem(key, raw); - } -+ Cookies.set(key, raw, { domain: 'cebg.games'}); ++ Cookies.set(key, raw, { domain: generateDomain() }); + // const local = getLocalStorage(); + // if (local) { + // local.setItem(key, raw); @@ -38,7 +48,7 @@ index c7f4db3..9e2d455 100644 - if (local) { - local.removeItem(key); - } -+ Cookies.remove(key); ++ Cookies.remove(key, { domain: generateDomain() }); + // const local = getLocalStorage(); + // if (local) { + // local.removeItem(key); diff --git a/src/chain/blockchain.ts b/src/chain/blockchain.ts index 2d64a3a..903057d 100644 --- a/src/chain/blockchain.ts +++ b/src/chain/blockchain.ts @@ -1,118 +1,129 @@ -import WalletConnectProvider from '@walletconnect/web3-provider' -import Web3 from 'web3' +import WalletConnectProvider from "@walletconnect/web3-provider"; +import Web3 from "web3"; import { AVAILABLE_CHAINS, CONTRACT_ADDRESS, IChainData, -} from '../configs/config_chain' +} from "../configs/config_chain"; import { EventBus, NEED_CHANGE_CHAIN, NEED_LOGIN, NEED_NONCE, SHOW_CHAIN_MODAL, -} from '../utils/event-bus' -import { hasMetamask, toHexChainId } from '../utils/chain.util' -import { AllChains } from '../configs/allchain' -import { ERC20ABI } from '../configs/contracts' -import { TransactionReceipt } from 'web3-core' -import { singleton } from '../decorator/singleton.decorator' -import { isMobile } from '../utils/browser' -import { UserModule } from '../module/UserModule' -import { getItem, removeItem, setItem } from '../utils/cookies' +} from "../utils/event-bus"; +import { hasMetamask, toHexChainId } from "../utils/chain.util"; +import { AllChains } from "../configs/allchain"; +import { ERC20ABI } from "../configs/contracts"; +import { TransactionReceipt } from "web3-core"; +import { singleton } from "../decorator/singleton.decorator"; +import { isMobile } from "../utils/browser"; +import { UserModule } from "../module/UserModule"; +import { getItem, removeItem, setItem } from "../utils/cookies"; const EIP721_DOMAIN_DATA = [ - { name: 'name', type: 'string' }, - { name: 'version', type: 'string' }, - { name: 'chainId', type: 'uint256' }, - { name: 'verifyingContract', type: 'address' }, -] + { name: "name", type: "string" }, + { name: "version", type: "string" }, + { name: "chainId", type: "uint256" }, + { name: "verifyingContract", type: "address" }, +]; -const CACHE_KEY = 'cebg_chain_cache_key' +const CACHE_KEY = "cebg_chain_cache_key"; @singleton export class Blockchain { - provider: any - web3: Web3 - currentChain = 0 + provider: any; + web3: Web3; + currentChain = 0; // 0: null, 1: metamask, 2: walletconnect - walletType = 0 - dataCached = false - instanceCacheMap: Map - public chainMap: Map = new Map() - public rpc: any = {} + walletType = 0; + dataCached = false; + instanceCacheMap: Map; + public chainMap: Map = new Map(); + public rpc: any = {}; constructor() { - const allChainMap: Map = new Map() + const allChainMap: Map = new Map(); for (const d of AllChains) { - const id = d.id - this.rpc[id] = d.rpc - allChainMap.set(id, d) + const id = d.id; + this.rpc[id] = d.rpc; + allChainMap.set(id, d); } for (const id of AVAILABLE_CHAINS) { - this.chainMap.set(id, allChainMap.get(id)!) + this.chainMap.set(id, allChainMap.get(id)!); } - this.loadCachedProvider() - this.instanceCacheMap = new Map() + this.loadCachedProvider(); + this.instanceCacheMap = new Map(); // UserModule.updateChainID(chainId) - EventBus.$on(NEED_LOGIN, this.connect.bind(this)) + EventBus.$on(NEED_LOGIN, this.connect.bind(this)); } get isWalletConnect() { - return !!this.walletType && !!this.currentChain + return !!this.walletType && !!this.currentChain; } get mallAddress() { - return CONTRACT_ADDRESS[this.currentChain]?.mall + return CONTRACT_ADDRESS[this.currentChain]?.mall; + } + + public async updateAccount() { + const accounts = await this.web3.eth.getAccounts(); + if (accounts && accounts.length > 0) { + UserModule.updateAccount(accounts[0]); + } } public get hexChainId() { - return toHexChainId(this.currentChain) + return toHexChainId(this.currentChain); } public async chainSelected(id: number) { if (!this.chainMap.has(id)) { - return + return; } - this.currentChain = id + this.currentChain = id; if (this.provider) { - await this.switchEthereumChain() + await this.switchEthereumChain(); } else { - await this.connectWallet(true) + await this.connectWallet(true); } } public async connectWallet(isManual: boolean) { - console.log('begin connect to wallet: ', this.walletType, this.currentChain) + console.log( + "begin connect to wallet: ", + this.walletType, + this.currentChain + ); if (this.walletType === 1) { - this.provider = await this.connectMetaMask() + this.provider = await this.connectMetaMask(); } else if (this.walletType === 2) { - this.provider = await this.connectWalletConnect() + this.provider = await this.connectWalletConnect(); } if (!this.provider) { - return + return; } - this.web3 = new Web3(this.provider) - const chainId = await this.web3.eth.getChainId() + this.web3 = new Web3(this.provider); + const chainId = await this.web3.eth.getChainId(); // await this.checkChain(chainId) - this.subscribeToEvents() - const accounts = await this.web3.eth.getAccounts() + this.subscribeToEvents(); + const accounts = await this.web3.eth.getAccounts(); if (accounts && accounts.length > 0) { - UserModule.updateAccount(accounts[0]) + UserModule.updateAccount(accounts[0]); } - if (!this.currentChain) this.currentChain = chainId - this.saveProvider() - UserModule.updateChainID(chainId) - UserModule.updateWalletStatus(true) - console.log('current login chain: ', chainId) - console.log('accountsLogin: ', accounts, UserModule.accountId) + if (!this.currentChain) this.currentChain = chainId; + this.saveProvider(); + UserModule.updateChainID(chainId); + UserModule.updateWalletStatus(true); + console.log("current login chain: ", chainId); + console.log("accountsLogin: ", accounts, UserModule.accountId); if (isManual) { - EventBus.$emit(NEED_NONCE) + EventBus.$emit(NEED_NONCE); } else { - UserModule.updateStep(1) + UserModule.updateStep(1); } - return { account: accounts[0], chainId } + return { account: accounts[0], chainId }; } /** @@ -127,9 +138,9 @@ export class Blockchain { if (!this.chainMap.has(chainId)) { // if (this.walletType === 1) { try { - await this.selectChain() + await this.selectChain(); } catch (err) { - await this.disconnect() + await this.disconnect(); } // } else if (this.walletType === 2) { // await this.disconnect() @@ -148,22 +159,22 @@ export class Blockchain { public async connect(isManual = false) { if (isMobile()) { if (hasMetamask()) { - this.walletType = 1 + this.walletType = 1; } else { - this.walletType = 2 + this.walletType = 2; } } else { if (hasMetamask()) { if (isManual && !this.walletType) { - this.walletType = await this.selectWallet() - return + this.walletType = await this.selectWallet(); + return; } } else { - this.walletType = 2 + this.walletType = 2; } } if (isManual || this.isWalletConnect) { - await this.connectWallet(isManual) + await this.connectWallet(isManual); } } @@ -176,15 +187,15 @@ export class Blockchain { return new Promise((resolve, reject) => { EventBus.$emit(SHOW_CHAIN_MODAL, { confirm: (id: number) => { - console.log('select wallet: ', id) - resolve && resolve(id) + console.log("select wallet: ", id); + resolve && resolve(id); }, cancel: (reason: any) => { - console.log('cancel select wallet: ', reason) - reject && reject(reason) + console.log("cancel select wallet: ", reason); + reject && reject(reason); }, - }) - }) + }); + }); } /** @@ -196,27 +207,27 @@ export class Blockchain { return new Promise((resolve, reject) => { EventBus.$emit(NEED_CHANGE_CHAIN, { confirm: async (id: number) => { - console.log('select chain: ', id) - this.currentChain = id + console.log("select chain: ", id); + this.currentChain = id; if (this.provider) { - await this.switchEthereumChain() + await this.switchEthereumChain(); } - resolve && resolve(id) + resolve && resolve(id); }, cancel: (reason: any) => { - console.log('cancel select chain: ', reason) - reject && reject(reason) + console.log("cancel select chain: ", reason); + reject && reject(reason); }, - }) - }) + }); + }); } public async connectMetaMask() { - let provider = null - if (typeof window.ethereum !== 'undefined') { - provider = window.ethereum + let provider = null; + if (typeof window.ethereum !== "undefined") { + provider = window.ethereum; try { - await provider.request({ method: 'eth_requestAccounts' }) + await provider.request({ method: "eth_requestAccounts" }); } catch (error) { if (error.code === -32002) { // const hexChainId = toHexChainId(this.currentChain) @@ -224,63 +235,65 @@ export class Blockchain { // method: 'wallet_switchEthereumChain', // params: [{ chainId: hexChainId }] // }) - throw new Error('MeatMask not login, Open MeatMask and login first') + throw new Error("MeatMask not login, Open MeatMask and login first"); } else { - throw new Error('User Rejected') + throw new Error("User Rejected"); } } } else if (window.web3) { - provider = window.web3.currentProvider + provider = window.web3.currentProvider; } else if (window.celo) { - provider = window.celo + provider = window.celo; } else { - throw new Error('No Web3 Provider found') + throw new Error("No Web3 Provider found"); } - return provider + return provider; } public async connectWalletConnect() { const provider = new WalletConnectProvider({ infuraId: process.env.VUE_APP_WALLET_INFURAID, rpc: this.rpc, - }) + }); try { - await provider.enable() + await provider.enable(); } catch (err) { - console.log('connect to wallet connect error: ', err) - await Promise.reject(err) + console.log("connect to wallet connect error: ", err); + await Promise.reject(err); } - return provider + return provider; } public async getContractInstance(address: string, abi: any = ERC20ABI) { if (!this.instanceCacheMap.has(address)) { const instance = new this.web3.eth.Contract(abi, address, { from: UserModule.accountId, - }) - this.instanceCacheMap.set(address, instance) + }); + this.instanceCacheMap.set(address, instance); } - return this.instanceCacheMap.get(address) + return this.instanceCacheMap.get(address); } public clearCachedProvider() { - console.log('clear cached provider') - removeItem(CACHE_KEY) + console.log("clear cached provider"); + removeItem(CACHE_KEY); } public loadCachedProvider() { - const dataStr = getItem(CACHE_KEY) + const dataStr = 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 - } + 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() + console.log("err parse cached json"); + this.clearCachedProvider(); } } } @@ -289,53 +302,56 @@ export class Blockchain { const data = { walletType: this.walletType, chainId: this.currentChain, - } - setItem(CACHE_KEY, JSON.stringify(data)) + }; + setItem(CACHE_KEY, JSON.stringify(data)); } public async disconnect() { try { - await UserModule.LogOut() - await this.provider?.disconnect() + await UserModule.LogOut(); + await this.provider?.disconnect(); } catch (err) {} - this.currentChain = 0 - this.walletType = 0 - this.instanceCacheMap.clear() - this.clearCachedProvider() - UserModule.updateStep(0) - UserModule.updateChainID(0) - UserModule.updateNonce('') - UserModule.updateAccount('') - UserModule.updateWalletStatus(false) + this.currentChain = 0; + this.walletType = 0; + this.instanceCacheMap.clear(); + this.clearCachedProvider(); + UserModule.updateStep(0); + UserModule.updateChainID(0); + UserModule.updateNonce(""); + UserModule.updateAccount(""); + UserModule.updateWalletStatus(false); } public subscribeToEvents = () => { // Subscribe to accounts change - this.provider.on('accountsChanged', async (accounts: string[]) => { - console.log('accountsChanged: ', accounts) + this.provider.on("accountsChanged", async (accounts: string[]) => { + console.log("accountsChanged: ", accounts); if (accounts && accounts.length > 0) { if (UserModule.accountId !== accounts[0]) { - await UserModule.LogOut() - location.reload() + this.clearCachedProvider(); + await UserModule.LogOut(); + setTimeout(() => { + location.reload(); + }, 1000); } } - }) + }); // Subscribe to chainId change - this.provider.on('chainChanged', async (chainId: string) => { - const chainIdNum = parseInt(chainId) - console.log('chainChanged', chainId, chainIdNum) - await this.checkChain(chainIdNum) - this.currentChain = chainIdNum - this.saveProvider() - UserModule.updateChainID(this.currentChain) - }) + this.provider.on("chainChanged", async (chainId: string) => { + const chainIdNum = parseInt(chainId); + console.log("chainChanged", chainId, chainIdNum); + await this.checkChain(chainIdNum); + this.currentChain = chainIdNum; + this.saveProvider(); + UserModule.updateChainID(this.currentChain); + }); // Subscribe to session disconnection - this.provider.on('disconnect', (err: any) => { - console.log('disconnect', err) - }) - } + this.provider.on("disconnect", (err: any) => { + console.log("disconnect", err); + }); + }; /** * change chain of metamask @@ -344,27 +360,27 @@ export class Blockchain { * @return {Promise} */ async switchEthereumChain(chainId?: number, cb?: () => void) { - chainId = chainId || this.currentChain - const hexChainId = toHexChainId(chainId) + chainId = chainId || this.currentChain; + const hexChainId = toHexChainId(chainId); const onChainChange = (chainId: string) => { - console.log('switchEthereumChain: ', chainId) - this.provider.removeListener('chainChanged', onChainChange) - cb && cb() - } - this.provider.on('chainChanged', onChainChange) + console.log("switchEthereumChain: ", chainId); + this.provider.removeListener("chainChanged", onChainChange); + cb && cb(); + }; + this.provider.on("chainChanged", onChainChange); try { await this.provider.request({ - method: 'wallet_switchEthereumChain', + method: "wallet_switchEthereumChain", params: [{ chainId: hexChainId }], - }) - console.log('switch chain success') + }); + console.log("switch chain success"); } catch (e) { - console.log('switch chain error: ', e) - if (e.code === 4902 || e.message.indexOf('Unrecognized chain ID') >= 0) { + console.log("switch chain error: ", e); + if (e.code === 4902 || e.message.indexOf("Unrecognized chain ID") >= 0) { try { - const data = this.chainMap.get(chainId)! + const data = this.chainMap.get(chainId)!; await this.provider.request({ - method: 'wallet_addEthereumChain', + method: "wallet_addEthereumChain", params: [ { chainId: hexChainId, @@ -378,11 +394,11 @@ export class Blockchain { rpcUrls: [data.rpc], }, ], - }) - console.log('add chain success') + }); + console.log("add chain success"); } catch (addError) { - console.error('add chain error: ', addError) - this.provider.removeListener('chainChanged', onChainChange) + console.error("add chain error: ", addError); + this.provider.removeListener("chainChanged", onChainChange); } } // console.error(e) @@ -390,13 +406,15 @@ export class Blockchain { } public async getTransactionReceipt(txHash: string) { - return this.web3.eth.getTransactionReceipt(txHash) + return this.web3.eth.getTransactionReceipt(txHash); } public async getTxConfirms(txhash: string) { - const receipt: TransactionReceipt = await this.getTransactionReceipt(txhash) - const latest = await this.web3.eth.getBlockNumber() - return latest - receipt.blockNumber + 1 + const receipt: TransactionReceipt = await this.getTransactionReceipt( + txhash + ); + const latest = await this.web3.eth.getBlockNumber(); + return latest - receipt.blockNumber + 1; } public async signPresale({ @@ -406,50 +424,50 @@ export class Blockchain { buyerAddress, netId, }: { - type: number | string - paymentTokenAddress: string - price: any - buyerAddress: string - netId?: any + type: number | string; + paymentTokenAddress: string; + price: any; + buyerAddress: string; + netId?: any; }) { - const nonce = (Math.random() * 100000) | 0 + const nonce = (Math.random() * 100000) | 0; const signMsg = { item: type, token: paymentTokenAddress, price: price, salt: nonce, - } - netId = netId || (await this.web3.eth.getChainId()) + }; + netId = netId || (await this.web3.eth.getChainId()); const signObj = { types: { EIP712Domain: EIP721_DOMAIN_DATA, set: [ - { name: 'item', type: 'uint256' }, - { name: 'token', type: 'address' }, - { name: 'price', type: 'uint256' }, - { name: 'salt', type: 'uint256' }, + { name: "item", type: "uint256" }, + { name: "token", type: "address" }, + { name: "price", type: "uint256" }, + { name: "salt", type: "uint256" }, ], }, - primaryType: 'set', + primaryType: "set", domain: { - name: 'BEBoxMall', - version: '1', + name: "BEBoxMall", + version: "1", chainId: netId, verifyingContract: this.mallAddress, }, message: signMsg, - } - const signature = await this.signData(signObj, buyerAddress) - return { nonce, signature } + }; + const signature = await this.signData(signObj, buyerAddress); + return { nonce, signature }; } public async increaseAllowance(address: string, price: string) { - const coinInstance: any = await this.getContractInstance(address) + const coinInstance: any = await this.getContractInstance(address); const res = await coinInstance.methods .increaseAllowance(this.mallAddress, price) - .send({ gas: 1000000 }) - console.log('increaseAllowance: ', res) + .send({ gas: 1000000 }); + console.log("increaseAllowance: ", res); } /** @@ -458,35 +476,35 @@ export class Blockchain { * @return {Promise} */ public async getBalance(address: string, account: string | null) { - account = account || UserModule.accountId - const coinInstance: any = await this.getContractInstance(address) - return await coinInstance.methods.balanceOf(account).call() + account = account || UserModule.accountId; + const coinInstance: any = await this.getContractInstance(address); + return await coinInstance.methods.balanceOf(account).call(); } public async transferToAccount( account: string, amount: number, - address: string, + address: string ) { - const amountBN = this.web3.utils.toBN(this.web3.utils.toWei(amount + '')) - const coinInstance: any = await this.getContractInstance(address) + const amountBN = this.web3.utils.toBN(this.web3.utils.toWei(amount + "")); + const coinInstance: any = await this.getContractInstance(address); return coinInstance.methods .transfer(account, amountBN) - .send({ gas: 1000000 }) + .send({ gas: 1000000 }); } public async signData(signObj: any, signer: string) { - const msgParams = JSON.stringify(signObj) - const from = signer - console.log('clicked, sending personal sign req', 'from', from, msgParams) - const params = [from, msgParams] + const msgParams = JSON.stringify(signObj); + const from = signer; + console.log("clicked, sending personal sign req", "from", from, msgParams); + const params = [from, msgParams]; const result: any = await this.sendCmd({ - method: 'eth_signTypedData_v4', + method: "eth_signTypedData_v4", params, from, - }) - console.log(result) - return result.result + }); + console.log(result); + return result.result; } public async sendCmd({ method, params, from }: any) { @@ -501,12 +519,12 @@ export class Blockchain { }, async function (err: any, result: any) { if (err) { - reject && reject(err) - return + reject && reject(err); + return; } - resolve && resolve(result) - }, - ) - }) + resolve && resolve(result); + } + ); + }); } } diff --git a/src/index.ts b/src/index.ts index 216b2b4..081a38a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -23,6 +23,9 @@ export class JCChain { return !!UserModule.token; } + get token() { + return UserModule.token; + } get account() { return UserModule.accountId; } diff --git a/src/utils/cookies.ts b/src/utils/cookies.ts index bc60468..c96ade3 100644 --- a/src/utils/cookies.ts +++ b/src/utils/cookies.ts @@ -1,20 +1,20 @@ -import Cookies from 'js-cookie' +import Cookies from "js-cookie"; -const languageKey = 'language' -export const getLanguage = () => Cookies.get(languageKey) +const languageKey = "language"; +export const getLanguage = () => Cookies.get(languageKey); export const setLanguage = (language: string) => - Cookies.set(languageKey, language) + Cookies.set(languageKey, language); -const sizeKey = 'size' -export const getSize = () => Cookies.get(sizeKey) -export const setSize = (size: string) => Cookies.set(sizeKey, size) +const sizeKey = "size"; +export const getSize = () => Cookies.get(sizeKey); +export const setSize = (size: string) => Cookies.set(sizeKey, size); -const miniKey = 'mini' -export const getMini = () => Cookies.get(miniKey) -export const setMini = (mini: string) => Cookies.set(miniKey, mini) +const miniKey = "mini"; +export const getMini = () => Cookies.get(miniKey); +export const setMini = (mini: string) => Cookies.set(miniKey, mini); // User -const tokenKey = 'vue_typescript_access_token' +const tokenKey = "vue_typescript_access_token"; // export const getToken = () => localStorage.getItem(tokenKey) // export const setToken = (token: string) => localStorage.setItem(tokenKey, token) // export const removeToken = () => localStorage.removeItem(tokenKey) @@ -22,11 +22,26 @@ const tokenKey = 'vue_typescript_access_token' // export const getItem = (key: string) => localStorage.getItem(key) // export const setItem = (key: string, val: string) => localStorage.setItem(miniKey, val) // export const removeItem = (key: string) => localStorage.removeItem(key) - -export const getToken = () => Cookies.get(tokenKey) -export const setToken = (token: string) => Cookies.set(tokenKey, token, { domain: 'cebg.games'}) -export const removeToken = () => Cookies.remove(tokenKey) - -export const getItem = (key: string) => Cookies.get(key) -export const setItem = (key: string, val: string) => Cookies.set(key, val, { domain: 'cebg.games'}) -export const removeItem = (key: string) => Cookies.remove(key) +export const generateDomain = () => { + let host = location.host; + let hostArr = host.split("."); + if (host.length > 1) { + host = hostArr.slice(hostArr.length - 2).join("."); + } + return host; +}; +export const getToken = () => Cookies.get(tokenKey); +export const setToken = (token: string) => { + const host = generateDomain(); + Cookies.set(tokenKey, token, { domain: host }); +}; +export const removeToken = () => + Cookies.remove(tokenKey, { domain: generateDomain() }); +//TODO:: +export const getItem = (key: string) => Cookies.get(key); +export const setItem = (key: string, val: string) => { + const host = generateDomain(); + Cookies.set(key, val, { domain: host }); +}; +export const removeItem = (key: string) => + Cookies.remove(key, { domain: generateDomain() });