import { singleton } from 'decorators/singleton' import logger from 'logger/logger' import { TaskType } from 'models/RequestTask' import { ConfirmQueue } from 'queue/confirm.queue' import Web3 from 'web3' import { TransactionReceipt, AddedAccount } from 'web3-core' import { ERC20Reactor } from './ERC20Reactor' import { ERC721Reactor } from './ERC721Reactor' import { HttpRetryProvider } from './HttpRetryProvider' import { WalletReactor } from './WalletReactor' @singleton export class BlockChain { private web3: Web3 instanceCacheMap: Map private accountMaster: AddedAccount public erc20Reactor: ERC20Reactor public erc721Reactor: ERC721Reactor public walletReactor: WalletReactor public confirmQueue: ConfirmQueue public currentBlockNum: number = 0 constructor() { const provider = new HttpRetryProvider([process.env.CHAIN_RPC_URL]) this.web3 = new Web3(provider) this.confirmQueue = new ConfirmQueue(this.web3) let key = process.env.CHAIN_MASTER_KEY this.accountMaster = this.web3.eth.accounts.wallet.add(key) this.instanceCacheMap = new Map() this.erc20Reactor = new ERC20Reactor({ web3: this.web3, address: process.env.CHAIN_FT_ADDRESS, }) this.erc721Reactor = new ERC721Reactor({ web3: this.web3, address: process.env.CHAIN_NFT_ADDRESS, }) this.walletReactor = new WalletReactor({ web3: this.web3, address: process.env.CHAIN_WALLET_ADDRESS, }) } public async getContractInstance(address: string, abi: any) { if (!this.instanceCacheMap.has(address)) { const instance = new this.web3.eth.Contract(abi, address, { from: this.accountMaster.address }) this.instanceCacheMap.set(address, instance) } return this.instanceCacheMap.get(address) } public async getTransactionReceipt(txHash: string) { 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 } public async updateCurrenBlockNum() { this.currentBlockNum = await this.web3.eth.getBlockNumber() logger.debug(`update block num: ${this.currentBlockNum}`) } public async generateFunAbi(reqData: any) { let taskType = reqData.type let abi switch (taskType) { case TaskType.MINT_FT: abi = await this.erc20Reactor.mint(reqData) break case TaskType.MINT_NFT: abi = await this.erc721Reactor.batchMint(reqData) break case TaskType.TRANSFER_FT: abi = await this.erc20Reactor.transfer(reqData) break case TaskType.TRANSFER_NFT: abi = await this.erc721Reactor.transfer(reqData) break case TaskType.MINT_PRESALE_BOX: abi = await this.erc721Reactor.mint(reqData) break } return abi } }