import { singleton } from '@/decorators/singleton.decorator' import { Blockchain } from '@/chain/blockchain' import { getNonce } from '@/api/User' import { AppModule } from '@/store/modules/app' import { UserModule } from '@/store/modules/user' import { Message } from 'element-ui' import { Chain } from '@/chain/Chain' import { AVAILABLE_CHAINS, IChainData } from '@/configs/config_chain' import { AllChains } from '@/configs/allchain' @singleton export default class ChainManager { bc: Blockchain instanceMap: Map public chainMap: Map = new Map() private _availableChains: Map = new Map() constructor() { this.bc = new Blockchain() this.instanceMap = new Map() for (const data of AllChains) { this.chainMap.set(data.id, data) } } get availableChains() { if (this._availableChains.size === 0) { for (const id of AVAILABLE_CHAINS) { const d = this.chainMap.get(id) if (d) { this._availableChains.set(id, d) } } } return this._availableChains } public async init() { if (this.bc.isWalletConnect) { try { await this.bc.connect() await this.getNance() } catch (err) { console.log('connect chain error: ', err) } } } get isLogined() { return !!UserModule.token && !!AppModule.step } public async logout() { await this.bc.disconnect() } public async login() { if (!AppModule.step) { try { await this.bc.connect(true) await this.checkNance() } catch (err) { Message({ message: err.message, type: 'error', duration: 5 * 1000 }) await Promise.reject(err) } } } public async checkNance() { try { let nonce = AppModule.nonce if (!nonce) { const preRequest: any = await getNonce({ account: AppModule.accountId, net_id: AppModule.chainId }) nonce = preRequest.nonce + '' } await UserModule.Login({ bcInstance: this.bc, account: AppModule.accountId, chainId: AppModule.chainId, nonce }) AppModule.updateStep(1) } catch (err) { console.log(err) await Promise.reject(err) } } public async getNance() { console.log('need get nance') try { const preRequest: any = await getNonce({ account: AppModule.accountId, net_id: AppModule.chainId }) console.log('success get nonce: ', preRequest) // if need check sign and has nonce val, store it if (preRequest.state) { AppModule.updateStep(1) } else if (!preRequest.state && preRequest.nonce) { if (UserModule.token) { await UserModule.LogOut() } AppModule.updateStep(0) AppModule.updateNonce(preRequest.nonce + '') } } catch (err) { Message({ message: 'Error get login nonce', type: 'error', duration: 5 * 1000 }) } } public async getInstance(address: string, chainId: number) { const key = `${chainId}_${address}` if (!this.instanceMap.has(key)) { const chain = new Chain(this.chainMap.get(chainId)!.rpc) const coinInstance = await chain.getCoinInstance(address) this.instanceMap.set(key, coinInstance) } return this.instanceMap.get(key) } public async getBalance(address: string, chainId: number) { const coinInstance = await this.getInstance(address, chainId) const balance = await coinInstance.methods.balanceOf(AppModule.accountId).call() console.log('balance: ', balance) return balance } // 转账 public async transferToAccount({ to, amount, chainId, address } : { to: string amount: number chainId: number address: string}) { const self = this if (chainId !== this.bc.currentChain) { return new Promise((resolve, reject) => { this.bc.switchEthereumChain(chainId, function() { self.bc.transferToAccount(to, amount, address) .then(res => { resolve && resolve(res) }) .catch(err => { reject && reject(err) }) }) }) } else { return this.bc.transferToAccount(to, amount, address) } } }