import { ethers } from 'ethers' import { apiUnlockOrMint, apiMintNft } from '@/utils/marketplace' const lockAbi = [ 'function lock(address nft, address to, uint256[] tokenIds) external', 'function unlockOrMint(address nft, tuple[] nftList, uint256 signTime, uint256 saltNonce, bytes signature) external' ] const erc721Abi = [ 'function approve(address to, uint256 tokenId) external', 'function getApproved(uint256 tokenId) public view returns (address)' ] const lockAddress = import.meta.env.VUE_APP_LOCKER_ADDRESS export class Locker { constructor(_chainInstance) { this.bc = _chainInstance } async lock(nft, tokenIds) { // call single method with abi and address console.log('lock nft', nft, tokenIds) await this.bc.checkPassportLogin(); await this.bc.checkAndChangeChain(); const nftContract = new ethers.Contract(nft, erc721Abi, this.bc.web3Provider.getSigner()) const address = this.bc.store.passportAddress console.log('lock', nft, address, tokenIds) for (let tokenId of tokenIds) { const addressApproval = await nftContract.getApproved(tokenId) if ((addressApproval || "").toLowerCase() != lockAddress.toLowerCase()) { const resApproval = await nftContract.approve(lockAddress, tokenId); await this.bc.web3Provider.waitForTransaction(resApproval.hash) console.debug('approve', resApproval.hash) } } const contract = new ethers.Contract(lockAddress, lockAbi, this.bc.web3Provider.getSigner()) const res = await contract.lock(nft, address, tokenIds) await this.bc.web3Provider.waitForTransaction(res.hash) return res.hash } async sendUnlockOrMint(provider, {to, data}) { const txHash = await provider.request({ method: 'eth_sendTransaction', params: [{ to, data }] }) console.log(txHash) return txHash } // 游戏内资产上链, 用于解锁或铸造 // 创世英雄, 普通英雄, 金砖 // imtbl上unlock必须使用passport的provider async unlockOrMintGameNft(nft, tokenIds) { console.log('unlock nft', nft, tokenIds) await this.bc.checkPassportLogin(); await this.bc.checkAndChangeChain(); const preDatas = { net_id: import.meta.env.VUE_APP_NET_ID, contract_address: nft, tokens: tokenIds.map(tokenId => {return { tokenId }}), } const passportToken = await this.bc.passportToken() const { errcode, errmsg, trans_req } = await apiUnlockOrMint(preDatas, passportToken) if (errcode) { throw new Error(errmsg) } const web3Provider = this.bc.passportProvider || this.bc.web3Provider return this.sendUnlockOrMint(web3Provider, trans_req) } // 游戏内资产上链, 只用于mint // 该方法会显示一个确认弹窗, 由用户选择mint到哪个地址 async mintNft(tokenIds) { console.log('mint hero', tokenIds) const { provider, address } = await this.bc.selectAddress({}) const preDatas = { to: address, hero_uniids: tokenIds, } const passportToken = await this.bc.passportToken() const { errcode, errmsg, trans_req } = await apiMintNft(preDatas, passportToken) if (errcode) { throw new Error(errmsg) } return this.sendUnlockOrMint(provider, trans_req) } }